fix: restrict visible aggregate providers

This commit is contained in:
Mikael Hugo 2026-05-05 16:50:05 +02:00
parent aeea733cd6
commit c6fe3b2b79
3 changed files with 73 additions and 5 deletions

View file

@ -114,8 +114,46 @@ describe("ModelRegistry.getModelsForProxy — basic", () => {
assert.equal(result.length, 2);
});
it("filters paid OpenRouter and OpenCode models while keeping subscribed OpenCode Go models", () => {
it("filters paid OpenRouter and OpenCode models while keeping zero-cost and subscribed models", () => {
const registry = createRegistry(() => true);
registry.registerProvider("openrouter", {
authMode: "none",
baseUrl: "https://openrouter.ai/api/v1",
api: "openai-completions",
streamSimple: noopStream,
models: [
{
id: "qwen/qwen3-coder:free",
name: "Qwen Free",
api: "openai-completions",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 128000,
maxTokens: 16384,
},
{
id: "z-ai/glm-5.1",
name: "GLM Paid",
api: "openai-completions",
reasoning: false,
input: ["text"],
cost: { input: 1, output: 1, cacheRead: 0, cacheWrite: 0 },
contextWindow: 128000,
maxTokens: 16384,
},
{
id: "zero-cost/non-free-slug",
name: "Zero Cost Non-Free Slug",
api: "openai-completions",
reasoning: false,
input: ["text"],
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
contextWindow: 128000,
maxTokens: 16384,
},
],
});
const available = registry.getAvailable();
assert.ok(
@ -133,8 +171,15 @@ describe("ModelRegistry.getModelsForProxy — basic", () => {
assert.ok(
available
.filter((m) => m.provider === "openrouter")
.every((m) => m.id.endsWith(":free")),
"every available OpenRouter model must use the :free SKU",
.every((m) => m.id.endsWith(":free") || m.cost?.input === 0),
"every available OpenRouter model must use the :free SKU or carry zero-cost metadata",
);
assert.ok(
available.some(
(m) =>
m.provider === "openrouter" && m.id === "zero-cost/non-free-slug",
),
"OpenRouter models with explicit zero-cost metadata should remain available",
);
assert.equal(
registry.find("openrouter", "z-ai/glm-5.1"),
@ -228,6 +273,21 @@ describe("ModelRegistry.getModelsForProxy — basic", () => {
);
});
it("hides Groq as a selectable LLM model provider", () => {
const registry = createRegistry(() => true);
const available = registry.getAvailable();
assert.ok(
!available.some((m) => m.provider === "groq"),
"Groq should not be listed or selected by SF provider policy",
);
assert.equal(
registry.find("groq", "llama-3.1-8b-instant"),
undefined,
"direct lookup should also hide Groq models",
);
});
it("hides Claude Code because it is not part of the managed provider pool", () => {
const registry = createRegistry(() => true);
const available = registry.getAvailable();

View file

@ -247,6 +247,7 @@ const HIDDEN_MODEL_PROVIDERS = new Set([
"claude-code",
"google",
"google-vertex",
"groq",
"github-copilot",
"xai",
"xiaomi-token-plan-ams",
@ -318,7 +319,10 @@ function isModelAllowedByBuiltInProviderPolicy(
return isMistralSelectionModel(model.id);
}
if (provider === "openrouter") {
return providerModelAllowEntryMatches(":free", modelKey);
return (
providerModelAllowEntryMatches(":free", modelKey) ||
isZeroCost(model.cost)
);
}
if (provider === "opencode") {
return (

View file

@ -37,6 +37,7 @@ const HIDDEN_MODEL_PROVIDERS = new Set([
"claude-code",
"google",
"google-vertex",
"groq",
"github-copilot",
"xai",
"xiaomi-token-plan-ams",
@ -106,7 +107,10 @@ function isModelAllowedByBuiltInProviderPolicy(provider, modelId, model) {
return isMistralSelectionModel(modelId);
}
if (providerKey === "openrouter") {
return providerModelAllowEntryMatches(":free", modelKey);
return (
providerModelAllowEntryMatches(":free", modelKey) ||
isZeroCost(model?.cost)
);
}
if (providerKey === "opencode") {
return (