mirror of
https://github.com/farion1231/cc-switch.git
synced 2026-10-26 01:34:51 +08:00
fix(opencode): add SiliconFlow provider presets (#4878)
This commit is contained in:
1 parent
cc81627a8e
commit
23dc945e89
2 files changed
+162
No files matched your search
@@ -3110,6 +3110,83 @@ export const opencodeProviderPresets: OpenCodeProviderPreset[] = [
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "SiliconFlow",
|
||||
family: "siliconflow",
|
||||
regionKey: "cn",
|
||||
websiteUrl: "https://siliconflow.cn",
|
||||
apiKeyUrl: "https://cloud.siliconflow.cn/i/YflgU2Ve",
|
||||
settingsConfig: {
|
||||
npm: "@ai-sdk/openai-compatible",
|
||||
name: "SiliconFlow",
|
||||
options: {
|
||||
baseURL: "https://api.siliconflow.cn/v1",
|
||||
apiKey: "",
|
||||
setCacheKey: true,
|
||||
},
|
||||
models: {
|
||||
"deepseek-ai/DeepSeek-V4-Flash": {
|
||||
name: "DeepSeek V4 Flash",
|
||||
reasoning: true,
|
||||
limit: { context: 1048576, output: 384000 },
|
||||
},
|
||||
},
|
||||
},
|
||||
category: "aggregator",
|
||||
isPartner: true,
|
||||
partnerPromotionKey: "siliconflow",
|
||||
icon: "siliconflow",
|
||||
iconColor: "#6E29F6",
|
||||
templateValues: {
|
||||
apiKey: {
|
||||
label: "API Key",
|
||||
placeholder: "sk-...",
|
||||
editorValue: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "SiliconFlow en",
|
||||
family: "siliconflow",
|
||||
regionKey: "intl",
|
||||
websiteUrl: "https://siliconflow.com",
|
||||
apiKeyUrl: "https://cloud.siliconflow.cn/i/YflgU2Ve",
|
||||
settingsConfig: {
|
||||
npm: "@ai-sdk/openai-compatible",
|
||||
name: "SiliconFlow en",
|
||||
options: {
|
||||
baseURL: "https://api.siliconflow.com/v1",
|
||||
apiKey: "",
|
||||
setCacheKey: true,
|
||||
},
|
||||
models: {
|
||||
"MiniMaxAI/MiniMax-M3": {
|
||||
name: "MiniMax M3",
|
||||
reasoning: true,
|
||||
limit: { context: 1048576, output: 131072 },
|
||||
modalities: { input: ["text", "image"], output: ["text"] },
|
||||
},
|
||||
"deepseek-ai/DeepSeek-V4.1-Flash": {
|
||||
name: "DeepSeek V4.1 Flash",
|
||||
reasoning: true,
|
||||
limit: { context: 1048576, output: 384000 },
|
||||
modalities: { input: ["text", "image"], output: ["text"] },
|
||||
},
|
||||
},
|
||||
},
|
||||
category: "aggregator",
|
||||
isPartner: true,
|
||||
partnerPromotionKey: "siliconflow",
|
||||
icon: "siliconflow",
|
||||
iconColor: "#000000",
|
||||
templateValues: {
|
||||
apiKey: {
|
||||
label: "API Key",
|
||||
placeholder: "sk-...",
|
||||
editorValue: "",
|
||||
},
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "AiHubMix",
|
||||
websiteUrl: "https://aihubmix.com",
|
||||
|
||||
@@ -4,6 +4,12 @@ import {
|
||||
opencodeNpmPackages,
|
||||
OPENCODE_PRESET_MODEL_VARIANTS,
|
||||
} from "@/config/opencodeProviderPresets";
|
||||
import { openclawProviderPresets } from "@/config/openclawProviderPresets";
|
||||
import { codexProviderPresets } from "@/config/codexProviderPresets";
|
||||
import {
|
||||
groupPresetRows,
|
||||
presetVersionLayout,
|
||||
} from "@/components/providers/forms/presetGroups";
|
||||
|
||||
describe("AWS Bedrock OpenCode Provider Presets", () => {
|
||||
it("should include @ai-sdk/amazon-bedrock in npm packages", () => {
|
||||
@@ -161,3 +167,82 @@ describe("OpenCode preset reasoning flags", () => {
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("OpenCode preset model limits", () => {
|
||||
// 预设走 V1 格式(npm),OpenCode 要求 limit 同时带 context 和 output,
|
||||
// 缺一个整份 opencode.json 报 Configuration is invalid,所有供应商一起不可用。
|
||||
it("declares both context and output whenever a limit is set", () => {
|
||||
for (const preset of opencodeProviderPresets) {
|
||||
for (const [id, model] of Object.entries(
|
||||
preset.settingsConfig.models ?? {},
|
||||
)) {
|
||||
if (model.limit === undefined) continue;
|
||||
expect(model.limit.context, `${preset.name} / ${id}`).toBeTypeOf(
|
||||
"number",
|
||||
);
|
||||
expect(model.limit.output, `${preset.name} / ${id}`).toBeTypeOf(
|
||||
"number",
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
describe("SiliconFlow OpenCode provider presets", () => {
|
||||
it.each(["SiliconFlow", "SiliconFlow en"])(
|
||||
"%s includes the current Codex preset models at the matching endpoint",
|
||||
(name) => {
|
||||
const preset = opencodeProviderPresets.find(
|
||||
(item) => item.name === name,
|
||||
)!;
|
||||
const openclaw = openclawProviderPresets.find(
|
||||
(item) => item.name === name,
|
||||
)!;
|
||||
const codex = codexProviderPresets.find((item) => item.name === name)!;
|
||||
|
||||
expect(preset).toBeDefined();
|
||||
expect(openclaw).toBeDefined();
|
||||
expect(codex).toBeDefined();
|
||||
expect(preset.settingsConfig.npm).toBe("@ai-sdk/openai-compatible");
|
||||
expect(preset.settingsConfig.options.baseURL).toBe(
|
||||
openclaw.settingsConfig.baseUrl,
|
||||
);
|
||||
expect(preset.settingsConfig.options.apiKey).toBe("");
|
||||
const codexModels = codex.modelCatalog ?? [];
|
||||
expect(codexModels.length).toBeGreaterThan(0);
|
||||
expect(Object.keys(preset.settingsConfig.models)).toEqual(
|
||||
expect.arrayContaining(codexModels.map((model) => model.model)),
|
||||
);
|
||||
for (const model of codexModels) {
|
||||
expect(preset.settingsConfig.models[model.model].limit?.context).toBe(
|
||||
model.contextWindow,
|
||||
);
|
||||
expect(preset.settingsConfig.models[model.model].reasoning).toBe(true);
|
||||
}
|
||||
expect(preset.category).toBe("aggregator");
|
||||
expect(preset.partnerPromotionKey).toBe(openclaw.partnerPromotionKey);
|
||||
expect(preset.icon).toBe(openclaw.icon);
|
||||
},
|
||||
);
|
||||
|
||||
it("groups both regions into one provider with a region selector", () => {
|
||||
const entries = opencodeProviderPresets.map((preset, index) => ({
|
||||
id: `opencode-${index}`,
|
||||
preset,
|
||||
}));
|
||||
const rows = groupPresetRows(entries).filter((row) =>
|
||||
row.versions.some(({ preset }) => preset.name.startsWith("SiliconFlow")),
|
||||
);
|
||||
|
||||
expect(rows).toHaveLength(1);
|
||||
expect(rows[0].family).toBe("siliconflow");
|
||||
expect(rows[0].versions.map(({ preset }) => preset.regionKey)).toEqual([
|
||||
"cn",
|
||||
"intl",
|
||||
]);
|
||||
expect(presetVersionLayout(rows[0].versions)).toEqual({
|
||||
kind: "single",
|
||||
dimension: "region",
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user