mirror of
https://github.com/openclaw/openclaw.git
synced 2026-04-17 20:21:13 +00:00
feat(qwen): add qwen provider and video generation
This commit is contained in:
@@ -14,8 +14,8 @@ describe("formatAuthDoctorHint", () => {
|
||||
provider: "qwen-portal",
|
||||
});
|
||||
|
||||
expect(hint).toContain("openclaw onboard --auth-choice modelstudio-api-key");
|
||||
expect(hint).toContain("modelstudio-api-key-cn");
|
||||
expect(hint).not.toContain("--provider modelstudio");
|
||||
expect(hint).toContain("openclaw onboard --auth-choice qwen-api-key");
|
||||
expect(hint).toContain("qwen-api-key-cn");
|
||||
expect(hint).not.toContain("--provider qwen");
|
||||
});
|
||||
});
|
||||
|
||||
@@ -13,7 +13,15 @@ import {
|
||||
} from "./model-auth.js";
|
||||
|
||||
vi.mock("../plugins/provider-runtime.js", () => ({
|
||||
buildProviderMissingAuthMessageWithPlugin: () => undefined,
|
||||
buildProviderMissingAuthMessageWithPlugin: (params: {
|
||||
provider: string;
|
||||
context: { listProfileIds: (providerId: string) => string[] };
|
||||
}) => {
|
||||
if (params.provider === "openai" && params.context.listProfileIds("openai-codex").length > 0) {
|
||||
return 'No API key found for provider "openai". Use openai-codex/gpt-5.4.';
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
formatProviderAuthProfileApiKeyWithPlugin: async () => undefined,
|
||||
refreshProviderOAuthCredentialWithPlugin: async () => null,
|
||||
resolveProviderSyntheticAuthWithPlugin: (params: {
|
||||
@@ -311,13 +319,13 @@ describe("getApiKeyForModel", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("resolves Model Studio API key from env", async () => {
|
||||
it("resolves Qwen API key from env", async () => {
|
||||
await withEnvAsync(
|
||||
{ [envVar("MODELSTUDIO", "API", "KEY")]: "modelstudio-test-key" },
|
||||
async () => {
|
||||
// pragma: allowlist secret
|
||||
const resolved = await resolveApiKeyForProvider({
|
||||
provider: "modelstudio",
|
||||
provider: "qwen",
|
||||
store: { version: 1, profiles: {} },
|
||||
});
|
||||
expect(resolved.apiKey).toBe("modelstudio-test-key");
|
||||
|
||||
@@ -157,10 +157,10 @@ describe("normalizeModelCompat", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("keeps supportsUsageInStreaming on for native ModelStudio endpoints", () => {
|
||||
it("keeps supportsUsageInStreaming on for native Qwen endpoints", () => {
|
||||
const model = {
|
||||
...baseModel(),
|
||||
provider: "modelstudio",
|
||||
provider: "qwen",
|
||||
baseUrl: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
|
||||
};
|
||||
delete (model as { compat?: unknown }).compat;
|
||||
|
||||
@@ -419,7 +419,7 @@ describe("model-selection", () => {
|
||||
"qwen-dashscope": {
|
||||
models: [{ id: "qwen-max" }],
|
||||
},
|
||||
modelstudio: {
|
||||
qwen: {
|
||||
models: [{ id: "qwen-max" }],
|
||||
},
|
||||
},
|
||||
|
||||
@@ -834,13 +834,13 @@ describe("openai transport stream", () => {
|
||||
expect(params.messages?.[0]?.content).toBe("Stable prefix\nDynamic suffix");
|
||||
});
|
||||
|
||||
it("uses system role and streaming usage compat for native ModelStudio completions providers", () => {
|
||||
it("uses system role and streaming usage compat for native Qwen completions providers", () => {
|
||||
const params = buildOpenAICompletionsParams(
|
||||
{
|
||||
id: "qwen3.6-plus",
|
||||
name: "Qwen 3.6 Plus",
|
||||
api: "openai-completions",
|
||||
provider: "modelstudio",
|
||||
provider: "qwen",
|
||||
baseUrl: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
|
||||
reasoning: true,
|
||||
input: ["text"],
|
||||
|
||||
@@ -561,7 +561,7 @@ describe("provider attribution", () => {
|
||||
|
||||
expect(
|
||||
resolveProviderRequestCapabilities({
|
||||
provider: "modelstudio",
|
||||
provider: "qwen",
|
||||
api: "openai-completions",
|
||||
baseUrl: "https://dashscope.aliyuncs.com/compatible-mode/v1",
|
||||
capability: "llm",
|
||||
@@ -745,9 +745,9 @@ describe("provider attribution", () => {
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "native ModelStudio completions",
|
||||
name: "native Qwen completions",
|
||||
input: {
|
||||
provider: "modelstudio",
|
||||
provider: "qwen",
|
||||
api: "openai-completions",
|
||||
baseUrl: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
|
||||
capability: "llm" as const,
|
||||
|
||||
@@ -295,6 +295,8 @@ function resolveKnownProviderFamily(provider: string | undefined): string {
|
||||
case "moonshot":
|
||||
case "kimi":
|
||||
return "moonshot";
|
||||
case "qwen":
|
||||
case "qwencloud":
|
||||
case "modelstudio":
|
||||
case "dashscope":
|
||||
return "modelstudio";
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
export function normalizeProviderId(provider: string): string {
|
||||
const normalized = provider.trim().toLowerCase();
|
||||
if (normalized === "modelstudio" || normalized === "qwencloud") {
|
||||
return "qwen";
|
||||
}
|
||||
if (normalized === "z.ai" || normalized === "z-ai") {
|
||||
return "zai";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user