fix: expose sf-scoped providers
This commit is contained in:
parent
ab6cad4c84
commit
aeea733cd6
12 changed files with 138 additions and 5 deletions
|
|
@ -38,4 +38,22 @@ describe("getEnvApiKey", () => {
|
|||
else process.env.GOOGLE_GENERATIVE_AI_API_KEY = savedGoogleGenerative;
|
||||
}
|
||||
});
|
||||
|
||||
it("uses the OpenCode Go subscription key before the Zen key", () => {
|
||||
const savedZen = process.env.OPENCODE_API_KEY;
|
||||
const savedGo = process.env.OPENCODE_GO_API_KEY;
|
||||
|
||||
process.env.OPENCODE_API_KEY = "zen-key";
|
||||
process.env.OPENCODE_GO_API_KEY = "go-key";
|
||||
|
||||
try {
|
||||
assert.equal(getEnvApiKey("opencode"), "zen-key");
|
||||
assert.equal(getEnvApiKey("opencode-go"), "go-key");
|
||||
} finally {
|
||||
if (savedZen === undefined) delete process.env.OPENCODE_API_KEY;
|
||||
else process.env.OPENCODE_API_KEY = savedZen;
|
||||
if (savedGo === undefined) delete process.env.OPENCODE_GO_API_KEY;
|
||||
else process.env.OPENCODE_GO_API_KEY = savedGo;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
|
|||
|
|
@ -166,7 +166,7 @@ export function getEnvApiKey(provider: any): string | undefined {
|
|||
"minimax-cn": "MINIMAX_CN_API_KEY",
|
||||
huggingface: "HF_TOKEN",
|
||||
opencode: "OPENCODE_API_KEY",
|
||||
"opencode-go": "OPENCODE_API_KEY",
|
||||
"opencode-go": ["OPENCODE_GO_API_KEY", "OPENCODE_API_KEY"],
|
||||
"kimi-coding": "KIMI_API_KEY",
|
||||
xiaomi: "XIAOMI_API_KEY",
|
||||
"xiaomi-token-plan-ams": "XIAOMI_API_KEY",
|
||||
|
|
|
|||
|
|
@ -101,7 +101,7 @@ export function getEnvApiKey(provider: string): string | undefined {
|
|||
"minimax-cn": "MINIMAX_CN_API_KEY",
|
||||
huggingface: "HF_TOKEN",
|
||||
opencode: "OPENCODE_API_KEY",
|
||||
"opencode-go": "OPENCODE_API_KEY",
|
||||
"opencode-go": ["OPENCODE_GO_API_KEY", "OPENCODE_API_KEY"],
|
||||
"kimi-coding": "KIMI_API_KEY",
|
||||
xiaomi: "XIAOMI_API_KEY",
|
||||
"xiaomi-token-plan-ams": "XIAOMI_API_KEY",
|
||||
|
|
|
|||
|
|
@ -352,7 +352,8 @@ ${chalk.bold("Environment Variables:")}
|
|||
MISTRAL_API_KEY - Mistral API key
|
||||
OLLAMA_API_KEY - Ollama Cloud API key
|
||||
MINIMAX_API_KEY - MiniMax API key
|
||||
OPENCODE_API_KEY - OpenCode Zen/OpenCode Go API key
|
||||
OPENCODE_API_KEY - OpenCode Zen API key
|
||||
OPENCODE_GO_API_KEY - OpenCode Go API key
|
||||
KIMI_API_KEY - Kimi For Coding API key
|
||||
AWS_PROFILE - AWS profile for Amazon Bedrock
|
||||
AWS_ACCESS_KEY_ID - AWS access key for Amazon Bedrock
|
||||
|
|
|
|||
|
|
@ -208,6 +208,26 @@ describe("ModelRegistry.getModelsForProxy — basic", () => {
|
|||
);
|
||||
});
|
||||
|
||||
it("hides Grok models even when they arrive through aggregators", () => {
|
||||
const registry = createRegistry(() => true);
|
||||
const available = registry.getAvailable();
|
||||
|
||||
assert.ok(
|
||||
!available.some(
|
||||
(m) =>
|
||||
m.provider === "xai" ||
|
||||
m.id.toLowerCase().includes("grok") ||
|
||||
m.id.toLowerCase().startsWith("x-ai/"),
|
||||
),
|
||||
"Grok/xAI models should not be visible through direct or aggregate providers",
|
||||
);
|
||||
assert.equal(
|
||||
registry.find("openrouter", "x-ai/grok-4:free"),
|
||||
undefined,
|
||||
"direct lookup should also block OpenRouter Grok SKUs",
|
||||
);
|
||||
});
|
||||
|
||||
it("hides Claude Code because it is not part of the managed provider pool", () => {
|
||||
const registry = createRegistry(() => true);
|
||||
const available = registry.getAvailable();
|
||||
|
|
|
|||
|
|
@ -311,6 +311,9 @@ function isModelAllowedByBuiltInProviderPolicy(
|
|||
if (HIDDEN_MODEL_PROVIDERS.has(provider)) {
|
||||
return false;
|
||||
}
|
||||
if (modelKey.includes("grok") || modelKey.startsWith("x-ai/")) {
|
||||
return false;
|
||||
}
|
||||
if (provider === "mistral") {
|
||||
return isMistralSelectionModel(model.id);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -71,8 +71,11 @@ const LLM_PROVIDER_IDS = [
|
|||
"google-gemini-cli",
|
||||
"groq",
|
||||
"openrouter",
|
||||
"zai",
|
||||
"mistral",
|
||||
"xiaomi",
|
||||
"opencode",
|
||||
"opencode-go",
|
||||
"ollama",
|
||||
"ollama-cloud",
|
||||
"custom-openai",
|
||||
|
|
@ -91,12 +94,23 @@ const OTHER_PROVIDERS = [
|
|||
label: "OpenRouter",
|
||||
hint: "200+ models — openrouter.ai/keys",
|
||||
},
|
||||
{ value: "zai", label: "ZAI", hint: "ZAI GLM — bigmodel.cn" },
|
||||
{ value: "mistral", label: "Mistral", hint: "console.mistral.ai/api-keys" },
|
||||
{
|
||||
value: "xiaomi",
|
||||
label: "Xiaomi MiMo",
|
||||
hint: "token-plan-ams.xiaomimimo.com",
|
||||
},
|
||||
{
|
||||
value: "opencode",
|
||||
label: "OpenCode Zen",
|
||||
hint: "free Zen models — OPENCODE_API_KEY",
|
||||
},
|
||||
{
|
||||
value: "opencode-go",
|
||||
label: "OpenCode Go",
|
||||
hint: "subscription — OPENCODE_GO_API_KEY",
|
||||
},
|
||||
{ value: "ollama-cloud", label: "Ollama Cloud" },
|
||||
{
|
||||
value: "custom-openai",
|
||||
|
|
|
|||
|
|
@ -60,6 +60,13 @@ export const PROVIDER_REGISTRY = [
|
|||
envVar: "MISTRAL_API_KEY",
|
||||
dashboardUrl: "console.mistral.ai",
|
||||
},
|
||||
{
|
||||
id: "zai",
|
||||
label: "ZAI",
|
||||
category: "llm",
|
||||
envVar: "ZAI_API_KEY",
|
||||
dashboardUrl: "bigmodel.cn",
|
||||
},
|
||||
{
|
||||
id: "xiaomi",
|
||||
label: "Xiaomi MiMo",
|
||||
|
|
@ -75,7 +82,7 @@ export const PROVIDER_REGISTRY = [
|
|||
},
|
||||
{
|
||||
id: "opencode",
|
||||
label: "OpenCode",
|
||||
label: "OpenCode Zen",
|
||||
category: "llm",
|
||||
envVar: "OPENCODE_API_KEY",
|
||||
dashboardUrl: "opencode.ai/zen",
|
||||
|
|
@ -84,7 +91,7 @@ export const PROVIDER_REGISTRY = [
|
|||
id: "opencode-go",
|
||||
label: "OpenCode Go",
|
||||
category: "llm",
|
||||
envVar: "OPENCODE_API_KEY",
|
||||
envVar: "OPENCODE_GO_API_KEY",
|
||||
dashboardUrl: "opencode.ai/zen",
|
||||
},
|
||||
{
|
||||
|
|
|
|||
|
|
@ -99,6 +99,9 @@ function isModelAllowedByBuiltInProviderPolicy(provider, modelId, model) {
|
|||
if (HIDDEN_MODEL_PROVIDERS.has(providerKey)) {
|
||||
return false;
|
||||
}
|
||||
if (modelKey.includes("grok") || modelKey.startsWith("x-ai/")) {
|
||||
return false;
|
||||
}
|
||||
if (providerKey === "mistral") {
|
||||
return isMistralSelectionModel(modelId);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -57,6 +57,7 @@ const SANITIZED_PROVIDER_ENV_KEYS = [
|
|||
"MINIMAX_CN_API_KEY",
|
||||
"HF_TOKEN",
|
||||
"OPENCODE_API_KEY",
|
||||
"OPENCODE_GO_API_KEY",
|
||||
"KIMI_API_KEY",
|
||||
"ALIBABA_API_KEY",
|
||||
"COPILOT_GITHUB_TOKEN",
|
||||
|
|
|
|||
|
|
@ -42,6 +42,7 @@ const ONBOARDING_ENV_KEYS = [
|
|||
"MINIMAX_CN_API_KEY",
|
||||
"HF_TOKEN",
|
||||
"OPENCODE_API_KEY",
|
||||
"OPENCODE_GO_API_KEY",
|
||||
"KIMI_API_KEY",
|
||||
"ALIBABA_API_KEY",
|
||||
"AWS_PROFILE",
|
||||
|
|
@ -396,6 +397,11 @@ test("boot and onboarding routes expose locked required state plus explicitly sk
|
|||
"groq",
|
||||
"openrouter",
|
||||
"mistral",
|
||||
"zai",
|
||||
"xiaomi",
|
||||
"opencode",
|
||||
"opencode-go",
|
||||
"ollama-cloud",
|
||||
]);
|
||||
const anthropicProvider = bootPayload.onboarding.required.providers.find(
|
||||
(provider: any) => provider.id === "anthropic",
|
||||
|
|
|
|||
|
|
@ -199,6 +199,31 @@ const REQUIRED_PROVIDER_CATALOG: RequiredProviderCatalogEntry[] = [
|
|||
supportsApiKey: true,
|
||||
supportsOAuth: false,
|
||||
},
|
||||
{ id: "zai", label: "ZAI", supportsApiKey: true, supportsOAuth: false },
|
||||
{
|
||||
id: "xiaomi",
|
||||
label: "Xiaomi MiMo",
|
||||
supportsApiKey: true,
|
||||
supportsOAuth: false,
|
||||
},
|
||||
{
|
||||
id: "opencode",
|
||||
label: "OpenCode Zen",
|
||||
supportsApiKey: true,
|
||||
supportsOAuth: false,
|
||||
},
|
||||
{
|
||||
id: "opencode-go",
|
||||
label: "OpenCode Go",
|
||||
supportsApiKey: true,
|
||||
supportsOAuth: false,
|
||||
},
|
||||
{
|
||||
id: "ollama-cloud",
|
||||
label: "Ollama Cloud",
|
||||
supportsApiKey: true,
|
||||
supportsOAuth: false,
|
||||
},
|
||||
];
|
||||
|
||||
const OPTIONAL_SECTION_CATALOG: OptionalSectionCatalogEntry[] = [
|
||||
|
|
@ -460,6 +485,41 @@ async function defaultValidateApiKey(
|
|||
"https://api.mistral.ai/v1/models",
|
||||
apiKey,
|
||||
);
|
||||
case "zai":
|
||||
return await validateBearerRequest(
|
||||
fetchImpl,
|
||||
providerId,
|
||||
"https://open.bigmodel.cn/api/paas/v4/models",
|
||||
apiKey,
|
||||
);
|
||||
case "xiaomi":
|
||||
return await validateBearerRequest(
|
||||
fetchImpl,
|
||||
providerId,
|
||||
"https://token-plan-ams.xiaomimimo.com/anthropic/v1/models",
|
||||
apiKey,
|
||||
);
|
||||
case "opencode":
|
||||
return await validateBearerRequest(
|
||||
fetchImpl,
|
||||
providerId,
|
||||
"https://opencode.ai/zen/v1/models",
|
||||
apiKey,
|
||||
);
|
||||
case "opencode-go":
|
||||
return await validateBearerRequest(
|
||||
fetchImpl,
|
||||
providerId,
|
||||
"https://opencode.ai/zen/go/v1/models",
|
||||
apiKey,
|
||||
);
|
||||
case "ollama-cloud":
|
||||
return await validateBearerRequest(
|
||||
fetchImpl,
|
||||
providerId,
|
||||
"https://ollama.com/api/tags",
|
||||
apiKey,
|
||||
);
|
||||
default:
|
||||
return {
|
||||
ok: false,
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue