feat(ai): add Qwen Token Plan as built-in provider (#6858)
Add Alibaba Cloud Model Studio Token Plan subscription service as two built-in API-key providers: qwen-token-plan (international, Singapore) and qwen-token-plan-cn (China, Beijing). Each provider exposes 15 text-generation models (Qwen, DeepSeek, GLM, Kimi, MiniMax) via the OpenAI-compatible endpoint with DashScope enable_thinking support. Model metadata is sourced from models.dev; qwen3.8-max-preview is hardcoded until models.dev includes it. Also fixes kimi-coding test references (k2p7 -> kimi-for-coding) after models.dev catalog update picked up by generate-models. Closes #6850
This commit is contained in:
@@ -1825,6 +1825,57 @@ async function loadModelsDevData(): Promise<Model<any>[]> {
|
||||
}
|
||||
}
|
||||
|
||||
// Process Alibaba Cloud Model Studio Token Plan models
|
||||
// Two regions (international / cn) with identical catalogs, separate
|
||||
// endpoints and API keys (sk-sp- prefix). models.dev keys are
|
||||
// "alibaba-token-plan[-cn]"; pi exposes them as "qwen-token-plan[-cn]".
|
||||
const qwenTokenPlanCompat: OpenAICompletionsCompat = {
|
||||
thinkingFormat: "qwen",
|
||||
supportsDeveloperRole: false,
|
||||
supportsStore: false,
|
||||
};
|
||||
const qwenTokenPlanVariants = [
|
||||
{
|
||||
source: "alibaba-token-plan",
|
||||
provider: "qwen-token-plan",
|
||||
baseUrl: "https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
|
||||
},
|
||||
{
|
||||
source: "alibaba-token-plan-cn",
|
||||
provider: "qwen-token-plan-cn",
|
||||
baseUrl: "https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",
|
||||
},
|
||||
] as const;
|
||||
|
||||
for (const { source, provider, baseUrl } of qwenTokenPlanVariants) {
|
||||
const providerModels = data[source]?.models;
|
||||
if (!providerModels) continue;
|
||||
|
||||
for (const [modelId, model] of Object.entries(providerModels)) {
|
||||
const m = model as ModelsDevModel;
|
||||
if (m.tool_call !== true) continue;
|
||||
|
||||
models.push({
|
||||
id: modelId,
|
||||
name: m.name || modelId,
|
||||
api: "openai-completions",
|
||||
provider,
|
||||
baseUrl,
|
||||
compat: qwenTokenPlanCompat,
|
||||
reasoning: m.reasoning === true,
|
||||
input: m.modalities?.input?.includes("image") ? ["text", "image"] : ["text"],
|
||||
cost: {
|
||||
input: m.cost?.input || 0,
|
||||
output: m.cost?.output || 0,
|
||||
cacheRead: m.cost?.cache_read || 0,
|
||||
cacheWrite: m.cost?.cache_write || 0,
|
||||
},
|
||||
contextWindow: m.limit?.context || 4096,
|
||||
maxTokens: m.limit?.output || 4096,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
console.log(`Loaded ${models.length} tool-capable models from models.dev`);
|
||||
return models;
|
||||
} catch (error) {
|
||||
@@ -2227,6 +2278,29 @@ async function generateModels() {
|
||||
});
|
||||
}
|
||||
|
||||
// Add qwen3.8-max-preview to Qwen Token Plan providers until models.dev includes it
|
||||
for (const qwenTpProvider of ["qwen-token-plan", "qwen-token-plan-cn"] as const) {
|
||||
if (!allModels.some((m) => m.provider === qwenTpProvider && m.id === "qwen3.8-max-preview")) {
|
||||
const baseUrl =
|
||||
qwenTpProvider === "qwen-token-plan"
|
||||
? "https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1"
|
||||
: "https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1";
|
||||
allModels.push({
|
||||
id: "qwen3.8-max-preview",
|
||||
name: "Qwen3.8 Max Preview",
|
||||
api: "openai-completions",
|
||||
provider: qwenTpProvider,
|
||||
baseUrl,
|
||||
compat: { thinkingFormat: "qwen", supportsDeveloperRole: false, supportsStore: false } satisfies OpenAICompletionsCompat,
|
||||
reasoning: true,
|
||||
input: ["text", "image"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 1000000,
|
||||
maxTokens: 65536,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// Add "auto" alias for openrouter/auto
|
||||
if (!allModels.some(m => m.provider === "openrouter" && m.id === "auto")) {
|
||||
allModels.push({
|
||||
|
||||
Reference in New Issue
Block a user