@openclaw/qwen-provider 0.0.0 → 2026.6.9-beta.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -1,3 +1,12 @@
1
- # @openclaw/qwen-provider
1
+ # OpenClaw Qwen Cloud Provider
2
2
 
3
- Reserved placeholder for the official OpenClaw plugin package. Use a published release version instead.
3
+ Official OpenClaw provider plugin for Qwen Cloud.
4
+
5
+ Install from OpenClaw:
6
+
7
+ ```bash
8
+ openclaw plugins install @openclaw/qwen-provider
9
+ openclaw gateway restart
10
+ ```
11
+
12
+ See <https://docs.openclaw.ai/providers/qwen> for setup and configuration.
package/dist/api.js ADDED
@@ -0,0 +1,4 @@
1
+ import { MODELSTUDIO_BASE_URL, MODELSTUDIO_CN_BASE_URL, MODELSTUDIO_DEFAULT_COST, MODELSTUDIO_DEFAULT_MODEL_ID, MODELSTUDIO_DEFAULT_MODEL_REF, MODELSTUDIO_GLOBAL_BASE_URL, MODELSTUDIO_MODEL_CATALOG, MODELSTUDIO_STANDARD_CN_BASE_URL, MODELSTUDIO_STANDARD_GLOBAL_BASE_URL, QWEN_36_PLUS_MODEL_ID, QWEN_BASE_URL, QWEN_CN_BASE_URL, QWEN_DEFAULT_COST, QWEN_DEFAULT_MODEL_ID, QWEN_DEFAULT_MODEL_REF, QWEN_GLOBAL_BASE_URL, QWEN_MODEL_CATALOG, QWEN_STANDARD_CN_BASE_URL, QWEN_STANDARD_GLOBAL_BASE_URL, applyModelStudioNativeStreamingUsageCompat, applyQwenNativeStreamingUsageCompat, buildModelStudioDefaultModelDefinition, buildModelStudioModelDefinition, buildQwenDefaultModelDefinition, buildQwenModelCatalogForBaseUrl, buildQwenModelDefinition, isNativeModelStudioBaseUrl, isNativeQwenBaseUrl, isQwen36PlusSupportedBaseUrl, isQwenCodingPlanBaseUrl } from "./models.js";
2
+ import { buildModelStudioProvider, buildQwenProvider } from "./provider-catalog.js";
3
+ import { createQwenThinkingWrapper, wrapQwenProviderStream } from "./stream.js";
4
+ export { MODELSTUDIO_BASE_URL, MODELSTUDIO_CN_BASE_URL, MODELSTUDIO_DEFAULT_COST, MODELSTUDIO_DEFAULT_MODEL_ID, MODELSTUDIO_DEFAULT_MODEL_REF, MODELSTUDIO_GLOBAL_BASE_URL, MODELSTUDIO_MODEL_CATALOG, MODELSTUDIO_STANDARD_CN_BASE_URL, MODELSTUDIO_STANDARD_GLOBAL_BASE_URL, QWEN_36_PLUS_MODEL_ID, QWEN_BASE_URL, QWEN_CN_BASE_URL, QWEN_DEFAULT_COST, QWEN_DEFAULT_MODEL_ID, QWEN_DEFAULT_MODEL_REF, QWEN_GLOBAL_BASE_URL, QWEN_MODEL_CATALOG, QWEN_STANDARD_CN_BASE_URL, QWEN_STANDARD_GLOBAL_BASE_URL, applyModelStudioNativeStreamingUsageCompat, applyQwenNativeStreamingUsageCompat, buildModelStudioDefaultModelDefinition, buildModelStudioModelDefinition, buildModelStudioProvider, buildQwenDefaultModelDefinition, buildQwenModelCatalogForBaseUrl, buildQwenModelDefinition, buildQwenProvider, createQwenThinkingWrapper, isNativeModelStudioBaseUrl, isNativeQwenBaseUrl, isQwen36PlusSupportedBaseUrl, isQwenCodingPlanBaseUrl, wrapQwenProviderStream };
package/dist/index.js ADDED
@@ -0,0 +1,201 @@
1
+ import { QWEN_36_PLUS_MODEL_ID, QWEN_DEFAULT_MODEL_REF, QWEN_OAUTH_DEFAULT_MODEL_REF, QWEN_OAUTH_PROVIDER_ID, applyQwenNativeStreamingUsageCompat, isQwenCodingPlanBaseUrl } from "./models.js";
2
+ import { buildQwenOAuthProvider, buildQwenProvider } from "./provider-catalog.js";
3
+ import { wrapQwenProviderStream } from "./stream.js";
4
+ import "./api.js";
5
+ import { buildQwenMediaUnderstandingProvider } from "./media-understanding-provider.js";
6
+ import { applyQwenConfig, applyQwenConfigCn, applyQwenOAuthConfig, applyQwenStandardConfig, applyQwenStandardConfigCn } from "./onboard.js";
7
+ import { buildQwenVideoGenerationProvider } from "./video-generation-provider.js";
8
+ import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-auth-api-key";
9
+ import { defineSingleProviderPluginEntry } from "openclaw/plugin-sdk/provider-entry";
10
+ //#region extensions/qwen/index.ts
11
+ const PROVIDER_ID = "qwen";
12
+ const LEGACY_PROVIDER_ID = "modelstudio";
13
+ const QWEN_OAUTH_AUTH_PROVIDER_IDS = [
14
+ QWEN_OAUTH_PROVIDER_ID,
15
+ "qwen-portal",
16
+ "qwen-cli"
17
+ ];
18
+ function normalizeProviderId(value) {
19
+ return value.trim().toLowerCase();
20
+ }
21
+ function resolveConfiguredQwenBaseUrl(config) {
22
+ const providers = config?.models?.providers;
23
+ if (!providers) return;
24
+ for (const [providerId, provider] of Object.entries(providers)) {
25
+ const normalized = normalizeProviderId(providerId);
26
+ if (normalized !== PROVIDER_ID && normalized !== LEGACY_PROVIDER_ID) continue;
27
+ const baseUrl = provider?.baseUrl?.trim();
28
+ if (baseUrl) return baseUrl;
29
+ }
30
+ }
31
+ var qwen_default = defineSingleProviderPluginEntry({
32
+ id: PROVIDER_ID,
33
+ name: "Qwen Provider",
34
+ description: "Bundled Qwen Cloud provider plugin",
35
+ provider: {
36
+ label: "Qwen Cloud",
37
+ docsPath: "/providers/qwen",
38
+ aliases: ["modelstudio", "qwencloud"],
39
+ auth: [
40
+ {
41
+ methodId: "standard-api-key-cn",
42
+ label: "Standard API Key for China (pay-as-you-go)",
43
+ hint: "Endpoint: dashscope.aliyuncs.com",
44
+ optionKey: "modelstudioStandardApiKeyCn",
45
+ flagName: "--modelstudio-standard-api-key-cn",
46
+ envVar: "QWEN_API_KEY",
47
+ promptMessage: "Enter Qwen Cloud API key (China standard endpoint)",
48
+ defaultModel: QWEN_DEFAULT_MODEL_REF,
49
+ applyConfig: (cfg) => applyQwenStandardConfigCn(cfg),
50
+ noteMessage: [
51
+ "Manage API keys: https://home.qwencloud.com/api-keys",
52
+ "Docs: https://docs.qwencloud.com/",
53
+ "Endpoint: dashscope.aliyuncs.com/compatible-mode/v1",
54
+ "Models: qwen3.6-plus, qwen3.5-plus, qwen3-coder-plus, etc."
55
+ ].join("\n"),
56
+ noteTitle: "Qwen Cloud Standard (China)",
57
+ wizard: {
58
+ choiceHint: "Endpoint: dashscope.aliyuncs.com",
59
+ groupLabel: "Qwen Cloud",
60
+ groupHint: "Standard / Coding Plan (CN / Global) + multimodal roadmap"
61
+ }
62
+ },
63
+ {
64
+ methodId: "standard-api-key",
65
+ label: "Standard API Key for Global/Intl (pay-as-you-go)",
66
+ hint: "Endpoint: dashscope-intl.aliyuncs.com",
67
+ optionKey: "modelstudioStandardApiKey",
68
+ flagName: "--modelstudio-standard-api-key",
69
+ envVar: "QWEN_API_KEY",
70
+ promptMessage: "Enter Qwen Cloud API key (Global/Intl standard endpoint)",
71
+ defaultModel: QWEN_DEFAULT_MODEL_REF,
72
+ applyConfig: (cfg) => applyQwenStandardConfig(cfg),
73
+ noteMessage: [
74
+ "Manage API keys: https://home.qwencloud.com/api-keys",
75
+ "Docs: https://docs.qwencloud.com/",
76
+ "Endpoint: dashscope-intl.aliyuncs.com/compatible-mode/v1",
77
+ "Models: qwen3.6-plus, qwen3.5-plus, qwen3-coder-plus, etc."
78
+ ].join("\n"),
79
+ noteTitle: "Qwen Cloud Standard (Global/Intl)",
80
+ wizard: {
81
+ choiceHint: "Endpoint: dashscope-intl.aliyuncs.com",
82
+ groupLabel: "Qwen Cloud",
83
+ groupHint: "Standard / Coding Plan (CN / Global) + multimodal roadmap"
84
+ }
85
+ },
86
+ {
87
+ methodId: "api-key-cn",
88
+ label: "Coding Plan API Key for China (subscription)",
89
+ hint: "Endpoint: coding.dashscope.aliyuncs.com",
90
+ optionKey: "modelstudioApiKeyCn",
91
+ flagName: "--modelstudio-api-key-cn",
92
+ envVar: "QWEN_API_KEY",
93
+ promptMessage: "Enter Qwen Cloud Coding Plan API key (China)",
94
+ defaultModel: QWEN_DEFAULT_MODEL_REF,
95
+ applyConfig: (cfg) => applyQwenConfigCn(cfg),
96
+ noteMessage: [
97
+ "Manage API keys: https://home.qwencloud.com/api-keys",
98
+ "Docs: https://docs.qwencloud.com/",
99
+ "Endpoint: coding.dashscope.aliyuncs.com",
100
+ "Models: qwen3.5-plus, glm-5, kimi-k2.5, MiniMax-M2.5, etc."
101
+ ].join("\n"),
102
+ noteTitle: "Qwen Cloud Coding Plan (China)",
103
+ wizard: {
104
+ choiceHint: "Endpoint: coding.dashscope.aliyuncs.com",
105
+ groupLabel: "Qwen Cloud",
106
+ groupHint: "Standard / Coding Plan (CN / Global) + multimodal roadmap"
107
+ }
108
+ },
109
+ {
110
+ methodId: "api-key",
111
+ label: "Coding Plan API Key for Global/Intl (subscription)",
112
+ hint: "Endpoint: coding-intl.dashscope.aliyuncs.com",
113
+ optionKey: "modelstudioApiKey",
114
+ flagName: "--modelstudio-api-key",
115
+ envVar: "QWEN_API_KEY",
116
+ promptMessage: "Enter Qwen Cloud Coding Plan API key (Global/Intl)",
117
+ defaultModel: QWEN_DEFAULT_MODEL_REF,
118
+ applyConfig: (cfg) => applyQwenConfig(cfg),
119
+ noteMessage: [
120
+ "Manage API keys: https://home.qwencloud.com/api-keys",
121
+ "Docs: https://docs.qwencloud.com/",
122
+ "Endpoint: coding-intl.dashscope.aliyuncs.com",
123
+ "Models: qwen3.5-plus, glm-5, kimi-k2.5, MiniMax-M2.5, etc."
124
+ ].join("\n"),
125
+ noteTitle: "Qwen Cloud Coding Plan (Global/Intl)",
126
+ wizard: {
127
+ choiceHint: "Endpoint: coding-intl.dashscope.aliyuncs.com",
128
+ groupLabel: "Qwen Cloud",
129
+ groupHint: "Standard / Coding Plan (CN / Global) + multimodal roadmap"
130
+ }
131
+ }
132
+ ],
133
+ catalog: { run: async (ctx) => {
134
+ const apiKey = ctx.resolveProviderApiKey(PROVIDER_ID).apiKey;
135
+ if (!apiKey) return null;
136
+ return { provider: {
137
+ ...buildQwenProvider({ baseUrl: resolveConfiguredQwenBaseUrl(ctx.config) ?? "https://coding-intl.dashscope.aliyuncs.com/v1" }),
138
+ apiKey
139
+ } };
140
+ } },
141
+ applyNativeStreamingUsageCompat: ({ providerConfig }) => applyQwenNativeStreamingUsageCompat(providerConfig),
142
+ wrapStreamFn: wrapQwenProviderStream,
143
+ normalizeConfig: ({ providerConfig }) => {
144
+ if (!isQwenCodingPlanBaseUrl(providerConfig.baseUrl)) return;
145
+ const models = providerConfig.models?.filter((model) => model.id !== QWEN_36_PLUS_MODEL_ID);
146
+ return models && models.length !== providerConfig.models?.length ? {
147
+ ...providerConfig,
148
+ models
149
+ } : void 0;
150
+ }
151
+ },
152
+ register(api) {
153
+ api.registerProvider({
154
+ id: QWEN_OAUTH_PROVIDER_ID,
155
+ label: "Qwen OAuth",
156
+ docsPath: "/providers/qwen",
157
+ aliases: ["qwen-portal", "qwen-cli"],
158
+ envVars: ["QWEN_API_KEY"],
159
+ auth: [createProviderApiKeyAuthMethod({
160
+ providerId: QWEN_OAUTH_PROVIDER_ID,
161
+ methodId: "api-key",
162
+ label: "Qwen OAuth token",
163
+ hint: "Portal token for portal.qwen.ai",
164
+ optionKey: "qwenOauthToken",
165
+ flagName: "--qwen-oauth-token",
166
+ envVar: "QWEN_API_KEY",
167
+ promptMessage: "Enter Qwen OAuth token",
168
+ defaultModel: QWEN_OAUTH_DEFAULT_MODEL_REF,
169
+ applyConfig: (cfg) => applyQwenOAuthConfig(cfg),
170
+ wizard: {
171
+ choiceId: QWEN_OAUTH_PROVIDER_ID,
172
+ choiceLabel: "Qwen OAuth",
173
+ choiceHint: "Portal token for portal.qwen.ai",
174
+ groupId: "qwen",
175
+ groupLabel: "Qwen Cloud",
176
+ groupHint: "Standard / Coding Plan / OAuth"
177
+ }
178
+ })],
179
+ catalog: {
180
+ order: "simple",
181
+ run: async (ctx) => {
182
+ const apiKey = QWEN_OAUTH_AUTH_PROVIDER_IDS.map((providerId) => ctx.resolveProviderApiKey(providerId).apiKey).find((candidate) => typeof candidate === "string" && candidate.length > 0);
183
+ if (!apiKey) return null;
184
+ return { provider: {
185
+ ...buildQwenOAuthProvider(),
186
+ apiKey
187
+ } };
188
+ }
189
+ },
190
+ staticCatalog: {
191
+ order: "simple",
192
+ run: async () => ({ provider: buildQwenOAuthProvider() })
193
+ },
194
+ wrapStreamFn: wrapQwenProviderStream
195
+ });
196
+ api.registerMediaUnderstandingProvider(buildQwenMediaUnderstandingProvider());
197
+ api.registerVideoGenerationProvider(buildQwenVideoGenerationProvider());
198
+ }
199
+ });
200
+ //#endregion
201
+ export { qwen_default as default };
@@ -0,0 +1,67 @@
1
+ import { QWEN_STANDARD_GLOBAL_BASE_URL } from "./models.js";
2
+ import { buildOpenAiCompatibleVideoRequestBody, coerceOpenAiCompatibleVideoText, describeImageWithModel, describeImagesWithModel, resolveMediaUnderstandingString } from "openclaw/plugin-sdk/media-understanding";
3
+ import { assertOkOrThrowHttpError, postJsonRequest, resolveProviderHttpRequestConfig } from "openclaw/plugin-sdk/provider-http";
4
+ //#region extensions/qwen/media-understanding-provider.ts
5
+ const DEFAULT_QWEN_VIDEO_MODEL = "qwen-vl-max-latest";
6
+ const DEFAULT_QWEN_VIDEO_PROMPT = "Describe the video in detail.";
7
+ async function describeQwenVideo(params) {
8
+ const fetchFn = params.fetchFn ?? fetch;
9
+ const model = resolveMediaUnderstandingString(params.model, DEFAULT_QWEN_VIDEO_MODEL);
10
+ const mime = resolveMediaUnderstandingString(params.mime, "video/mp4");
11
+ const prompt = resolveMediaUnderstandingString(params.prompt, DEFAULT_QWEN_VIDEO_PROMPT);
12
+ const { baseUrl, allowPrivateNetwork, headers, dispatcherPolicy } = resolveProviderHttpRequestConfig({
13
+ baseUrl: params.baseUrl,
14
+ defaultBaseUrl: QWEN_STANDARD_GLOBAL_BASE_URL,
15
+ headers: params.headers,
16
+ request: params.request,
17
+ defaultHeaders: {
18
+ "content-type": "application/json",
19
+ authorization: `Bearer ${params.apiKey}`
20
+ },
21
+ provider: "qwen",
22
+ api: "openai-completions",
23
+ capability: "video",
24
+ transport: "media-understanding"
25
+ });
26
+ const { response: res, release } = await postJsonRequest({
27
+ url: `${baseUrl}/chat/completions`,
28
+ headers,
29
+ body: buildOpenAiCompatibleVideoRequestBody({
30
+ model,
31
+ prompt,
32
+ mime,
33
+ buffer: params.buffer
34
+ }),
35
+ timeoutMs: params.timeoutMs,
36
+ fetchFn,
37
+ allowPrivateNetwork,
38
+ dispatcherPolicy
39
+ });
40
+ try {
41
+ await assertOkOrThrowHttpError(res, "Qwen video description failed");
42
+ const text = coerceOpenAiCompatibleVideoText(await res.json());
43
+ if (!text) throw new Error("Qwen video description response missing content");
44
+ return {
45
+ text,
46
+ model
47
+ };
48
+ } finally {
49
+ await release();
50
+ }
51
+ }
52
+ function buildQwenMediaUnderstandingProvider() {
53
+ return {
54
+ id: "qwen",
55
+ capabilities: ["image", "video"],
56
+ defaultModels: {
57
+ image: "qwen-vl-max-latest",
58
+ video: DEFAULT_QWEN_VIDEO_MODEL
59
+ },
60
+ autoPriority: { video: 15 },
61
+ describeImage: describeImageWithModel,
62
+ describeImages: describeImagesWithModel,
63
+ describeVideo: describeQwenVideo
64
+ };
65
+ }
66
+ //#endregion
67
+ export { buildQwenMediaUnderstandingProvider, describeQwenVideo };
@@ -0,0 +1,2 @@
1
+ import { MODELSTUDIO_CN_BASE_URL, MODELSTUDIO_DEFAULT_COST, MODELSTUDIO_DEFAULT_MODEL_ID, MODELSTUDIO_DEFAULT_MODEL_REF, MODELSTUDIO_GLOBAL_BASE_URL, MODELSTUDIO_STANDARD_CN_BASE_URL, MODELSTUDIO_STANDARD_GLOBAL_BASE_URL, QWEN_CN_BASE_URL, QWEN_DEFAULT_COST, QWEN_DEFAULT_MODEL_ID, QWEN_DEFAULT_MODEL_REF, QWEN_GLOBAL_BASE_URL, QWEN_STANDARD_CN_BASE_URL, QWEN_STANDARD_GLOBAL_BASE_URL, buildModelStudioDefaultModelDefinition, buildModelStudioModelDefinition, buildQwenDefaultModelDefinition, buildQwenModelDefinition } from "./models.js";
2
+ export { MODELSTUDIO_CN_BASE_URL, MODELSTUDIO_DEFAULT_COST, MODELSTUDIO_DEFAULT_MODEL_ID, MODELSTUDIO_DEFAULT_MODEL_REF, MODELSTUDIO_GLOBAL_BASE_URL, MODELSTUDIO_STANDARD_CN_BASE_URL, MODELSTUDIO_STANDARD_GLOBAL_BASE_URL, QWEN_CN_BASE_URL, QWEN_DEFAULT_COST, QWEN_DEFAULT_MODEL_ID, QWEN_DEFAULT_MODEL_REF, QWEN_GLOBAL_BASE_URL, QWEN_STANDARD_CN_BASE_URL, QWEN_STANDARD_GLOBAL_BASE_URL, buildModelStudioDefaultModelDefinition, buildModelStudioModelDefinition, buildQwenDefaultModelDefinition, buildQwenModelDefinition };
package/dist/models.js ADDED
@@ -0,0 +1,175 @@
1
+ import { applyProviderNativeStreamingUsageCompat, supportsNativeStreamingUsageCompat } from "openclaw/plugin-sdk/provider-catalog-shared";
2
+ //#region extensions/qwen/models.ts
3
+ const QWEN_BASE_URL = "https://coding-intl.dashscope.aliyuncs.com/v1";
4
+ const QWEN_GLOBAL_BASE_URL = QWEN_BASE_URL;
5
+ const QWEN_CN_BASE_URL = "https://coding.dashscope.aliyuncs.com/v1";
6
+ const QWEN_STANDARD_CN_BASE_URL = "https://dashscope.aliyuncs.com/compatible-mode/v1";
7
+ const QWEN_STANDARD_GLOBAL_BASE_URL = "https://dashscope-intl.aliyuncs.com/compatible-mode/v1";
8
+ const QWEN_OAUTH_PROVIDER_ID = "qwen-oauth";
9
+ const QWEN_OAUTH_BASE_URL = "https://portal.qwen.ai/v1";
10
+ const QWEN_DEFAULT_MODEL_ID = "qwen3.5-plus";
11
+ const QWEN_36_PLUS_MODEL_ID = "qwen3.6-plus";
12
+ const QWEN_DEFAULT_COST = {
13
+ input: 0,
14
+ output: 0,
15
+ cacheRead: 0,
16
+ cacheWrite: 0
17
+ };
18
+ const QWEN_DEFAULT_MODEL_REF = `qwen/${QWEN_DEFAULT_MODEL_ID}`;
19
+ const QWEN_OAUTH_DEFAULT_MODEL_REF = `qwen-oauth/${QWEN_DEFAULT_MODEL_ID}`;
20
+ const QWEN_MODEL_CATALOG = [
21
+ {
22
+ id: "qwen3.5-plus",
23
+ name: "qwen3.5-plus",
24
+ reasoning: false,
25
+ input: ["text", "image"],
26
+ cost: QWEN_DEFAULT_COST,
27
+ contextWindow: 1e6,
28
+ maxTokens: 65536
29
+ },
30
+ {
31
+ id: QWEN_36_PLUS_MODEL_ID,
32
+ name: QWEN_36_PLUS_MODEL_ID,
33
+ reasoning: false,
34
+ input: ["text", "image"],
35
+ cost: QWEN_DEFAULT_COST,
36
+ contextWindow: 1e6,
37
+ maxTokens: 65536
38
+ },
39
+ {
40
+ id: "qwen3-max-2026-01-23",
41
+ name: "qwen3-max-2026-01-23",
42
+ reasoning: false,
43
+ input: ["text"],
44
+ cost: QWEN_DEFAULT_COST,
45
+ contextWindow: 262144,
46
+ maxTokens: 65536
47
+ },
48
+ {
49
+ id: "qwen3-coder-next",
50
+ name: "qwen3-coder-next",
51
+ reasoning: false,
52
+ input: ["text"],
53
+ cost: QWEN_DEFAULT_COST,
54
+ contextWindow: 262144,
55
+ maxTokens: 65536
56
+ },
57
+ {
58
+ id: "qwen3-coder-plus",
59
+ name: "qwen3-coder-plus",
60
+ reasoning: false,
61
+ input: ["text"],
62
+ cost: QWEN_DEFAULT_COST,
63
+ contextWindow: 1e6,
64
+ maxTokens: 65536
65
+ },
66
+ {
67
+ id: "MiniMax-M2.5",
68
+ name: "MiniMax-M2.5",
69
+ reasoning: true,
70
+ input: ["text"],
71
+ cost: QWEN_DEFAULT_COST,
72
+ contextWindow: 1e6,
73
+ maxTokens: 65536
74
+ },
75
+ {
76
+ id: "glm-5",
77
+ name: "glm-5",
78
+ reasoning: false,
79
+ input: ["text"],
80
+ cost: QWEN_DEFAULT_COST,
81
+ contextWindow: 202752,
82
+ maxTokens: 16384
83
+ },
84
+ {
85
+ id: "glm-4.7",
86
+ name: "glm-4.7",
87
+ reasoning: false,
88
+ input: ["text"],
89
+ cost: QWEN_DEFAULT_COST,
90
+ contextWindow: 202752,
91
+ maxTokens: 16384
92
+ },
93
+ {
94
+ id: "kimi-k2.5",
95
+ name: "kimi-k2.5",
96
+ reasoning: false,
97
+ input: ["text", "image"],
98
+ cost: QWEN_DEFAULT_COST,
99
+ contextWindow: 262144,
100
+ maxTokens: 32768
101
+ }
102
+ ];
103
+ function isQwenCodingPlanBaseUrl(baseUrl) {
104
+ const trimmed = baseUrl?.trim();
105
+ if (!trimmed) return false;
106
+ try {
107
+ const hostname = new URL(trimmed).hostname.toLowerCase().replace(/\.+$/, "");
108
+ return hostname === "coding.dashscope.aliyuncs.com" || hostname === "coding-intl.dashscope.aliyuncs.com";
109
+ } catch {
110
+ return false;
111
+ }
112
+ }
113
+ function isQwen36PlusSupportedBaseUrl(baseUrl) {
114
+ return !isQwenCodingPlanBaseUrl(baseUrl);
115
+ }
116
+ function buildQwenModelCatalogForBaseUrl(baseUrl) {
117
+ return isQwen36PlusSupportedBaseUrl(baseUrl) ? QWEN_MODEL_CATALOG : QWEN_MODEL_CATALOG.filter((model) => model.id !== QWEN_36_PLUS_MODEL_ID);
118
+ }
119
+ function isNativeQwenBaseUrl(baseUrl) {
120
+ return supportsNativeStreamingUsageCompat({
121
+ providerId: "qwen",
122
+ baseUrl
123
+ });
124
+ }
125
+ function applyQwenNativeStreamingUsageCompat(provider) {
126
+ return applyProviderNativeStreamingUsageCompat({
127
+ providerId: "qwen",
128
+ providerConfig: provider
129
+ });
130
+ }
131
+ function buildQwenModelDefinition(params) {
132
+ const catalog = QWEN_MODEL_CATALOG.find((model) => model.id === params.id);
133
+ return {
134
+ id: params.id,
135
+ name: params.name ?? catalog?.name ?? params.id,
136
+ reasoning: params.reasoning ?? catalog?.reasoning ?? false,
137
+ input: params.input ?? (catalog?.input ? [...catalog.input] : ["text"]),
138
+ cost: params.cost ?? catalog?.cost ?? QWEN_DEFAULT_COST,
139
+ contextWindow: params.contextWindow ?? catalog?.contextWindow ?? 262144,
140
+ maxTokens: params.maxTokens ?? catalog?.maxTokens ?? 65536
141
+ };
142
+ }
143
+ function buildQwenDefaultModelDefinition() {
144
+ return buildQwenModelDefinition({ id: QWEN_DEFAULT_MODEL_ID });
145
+ }
146
+ function buildQwenOAuthModelCatalog() {
147
+ return QWEN_MODEL_CATALOG.map((model) => ({
148
+ ...model,
149
+ maxTokens: 65536
150
+ }));
151
+ }
152
+ /** @deprecated Use QWEN_BASE_URL. */
153
+ const MODELSTUDIO_BASE_URL = QWEN_BASE_URL;
154
+ /** @deprecated Use QWEN_GLOBAL_BASE_URL. */
155
+ const MODELSTUDIO_GLOBAL_BASE_URL = QWEN_GLOBAL_BASE_URL;
156
+ /** @deprecated Use QWEN_CN_BASE_URL. */
157
+ const MODELSTUDIO_CN_BASE_URL = QWEN_CN_BASE_URL;
158
+ /** @deprecated Use QWEN_STANDARD_CN_BASE_URL. */
159
+ const MODELSTUDIO_STANDARD_CN_BASE_URL = QWEN_STANDARD_CN_BASE_URL;
160
+ /** @deprecated Use QWEN_STANDARD_GLOBAL_BASE_URL. */
161
+ const MODELSTUDIO_STANDARD_GLOBAL_BASE_URL = QWEN_STANDARD_GLOBAL_BASE_URL;
162
+ /** @deprecated Use QWEN_DEFAULT_MODEL_ID. */
163
+ const MODELSTUDIO_DEFAULT_MODEL_ID = QWEN_DEFAULT_MODEL_ID;
164
+ /** @deprecated Use QWEN_DEFAULT_COST. */
165
+ const MODELSTUDIO_DEFAULT_COST = QWEN_DEFAULT_COST;
166
+ /** @deprecated Use qwen/${QWEN_DEFAULT_MODEL_ID}. */
167
+ const MODELSTUDIO_DEFAULT_MODEL_REF = `modelstudio/${QWEN_DEFAULT_MODEL_ID}`;
168
+ /** @deprecated Use QWEN_MODEL_CATALOG. */
169
+ const MODELSTUDIO_MODEL_CATALOG = QWEN_MODEL_CATALOG;
170
+ const isNativeModelStudioBaseUrl = isNativeQwenBaseUrl;
171
+ const applyModelStudioNativeStreamingUsageCompat = applyQwenNativeStreamingUsageCompat;
172
+ const buildModelStudioModelDefinition = buildQwenModelDefinition;
173
+ const buildModelStudioDefaultModelDefinition = buildQwenDefaultModelDefinition;
174
+ //#endregion
175
+ export { MODELSTUDIO_BASE_URL, MODELSTUDIO_CN_BASE_URL, MODELSTUDIO_DEFAULT_COST, MODELSTUDIO_DEFAULT_MODEL_ID, MODELSTUDIO_DEFAULT_MODEL_REF, MODELSTUDIO_GLOBAL_BASE_URL, MODELSTUDIO_MODEL_CATALOG, MODELSTUDIO_STANDARD_CN_BASE_URL, MODELSTUDIO_STANDARD_GLOBAL_BASE_URL, QWEN_36_PLUS_MODEL_ID, QWEN_BASE_URL, QWEN_CN_BASE_URL, QWEN_DEFAULT_COST, QWEN_DEFAULT_MODEL_ID, QWEN_DEFAULT_MODEL_REF, QWEN_GLOBAL_BASE_URL, QWEN_MODEL_CATALOG, QWEN_OAUTH_BASE_URL, QWEN_OAUTH_DEFAULT_MODEL_REF, QWEN_OAUTH_PROVIDER_ID, QWEN_STANDARD_CN_BASE_URL, QWEN_STANDARD_GLOBAL_BASE_URL, applyModelStudioNativeStreamingUsageCompat, applyQwenNativeStreamingUsageCompat, buildModelStudioDefaultModelDefinition, buildModelStudioModelDefinition, buildQwenDefaultModelDefinition, buildQwenModelCatalogForBaseUrl, buildQwenModelDefinition, buildQwenOAuthModelCatalog, isNativeModelStudioBaseUrl, isNativeQwenBaseUrl, isQwen36PlusSupportedBaseUrl, isQwenCodingPlanBaseUrl };
@@ -0,0 +1,53 @@
1
+ import { QWEN_CN_BASE_URL, QWEN_DEFAULT_MODEL_REF, QWEN_GLOBAL_BASE_URL, QWEN_OAUTH_DEFAULT_MODEL_REF, QWEN_OAUTH_PROVIDER_ID, QWEN_STANDARD_CN_BASE_URL, QWEN_STANDARD_GLOBAL_BASE_URL } from "./models.js";
2
+ import { buildQwenOAuthProvider, buildQwenProvider } from "./provider-catalog.js";
3
+ import { createModelCatalogPresetAppliers } from "openclaw/plugin-sdk/provider-onboard";
4
+ //#region extensions/qwen/onboard.ts
5
+ const qwenPresetAppliers = createModelCatalogPresetAppliers({
6
+ primaryModelRef: QWEN_DEFAULT_MODEL_REF,
7
+ resolveParams: (_cfg, baseUrl) => {
8
+ const provider = buildQwenProvider({ baseUrl });
9
+ return {
10
+ providerId: "qwen",
11
+ api: provider.api ?? "openai-completions",
12
+ baseUrl,
13
+ catalogModels: provider.models ?? [],
14
+ aliases: [...(provider.models ?? []).flatMap((model) => [`qwen/${model.id}`, `modelstudio/${model.id}`]), {
15
+ modelRef: QWEN_DEFAULT_MODEL_REF,
16
+ alias: "Qwen"
17
+ }]
18
+ };
19
+ }
20
+ });
21
+ const qwenOAuthPresetAppliers = createModelCatalogPresetAppliers({
22
+ primaryModelRef: QWEN_OAUTH_DEFAULT_MODEL_REF,
23
+ resolveParams: () => {
24
+ const provider = buildQwenOAuthProvider();
25
+ return {
26
+ providerId: QWEN_OAUTH_PROVIDER_ID,
27
+ api: provider.api ?? "openai-completions",
28
+ baseUrl: provider.baseUrl,
29
+ catalogModels: provider.models ?? [],
30
+ aliases: [...(provider.models ?? []).map((model) => `qwen-oauth/${model.id}`), {
31
+ modelRef: QWEN_OAUTH_DEFAULT_MODEL_REF,
32
+ alias: "Qwen OAuth"
33
+ }]
34
+ };
35
+ }
36
+ });
37
+ function applyQwenConfig(cfg) {
38
+ return qwenPresetAppliers.applyConfig(cfg, QWEN_GLOBAL_BASE_URL);
39
+ }
40
+ function applyQwenConfigCn(cfg) {
41
+ return qwenPresetAppliers.applyConfig(cfg, QWEN_CN_BASE_URL);
42
+ }
43
+ function applyQwenStandardConfig(cfg) {
44
+ return qwenPresetAppliers.applyConfig(cfg, QWEN_STANDARD_GLOBAL_BASE_URL);
45
+ }
46
+ function applyQwenStandardConfigCn(cfg) {
47
+ return qwenPresetAppliers.applyConfig(cfg, QWEN_STANDARD_CN_BASE_URL);
48
+ }
49
+ function applyQwenOAuthConfig(cfg) {
50
+ return qwenOAuthPresetAppliers.applyConfig(cfg);
51
+ }
52
+ //#endregion
53
+ export { applyQwenConfig, applyQwenConfigCn, applyQwenOAuthConfig, applyQwenStandardConfig, applyQwenStandardConfigCn };
@@ -0,0 +1,20 @@
1
+ import { QWEN_OAUTH_BASE_URL, buildQwenModelCatalogForBaseUrl, buildQwenOAuthModelCatalog } from "./models.js";
2
+ //#region extensions/qwen/provider-catalog.ts
3
+ function buildQwenProvider(params) {
4
+ const baseUrl = params?.baseUrl ?? "https://coding-intl.dashscope.aliyuncs.com/v1";
5
+ return {
6
+ baseUrl,
7
+ api: "openai-completions",
8
+ models: buildQwenModelCatalogForBaseUrl(baseUrl).map((model) => Object.assign({}, model))
9
+ };
10
+ }
11
+ function buildQwenOAuthProvider() {
12
+ return {
13
+ baseUrl: QWEN_OAUTH_BASE_URL,
14
+ api: "openai-completions",
15
+ models: buildQwenOAuthModelCatalog().map((model) => Object.assign({}, model))
16
+ };
17
+ }
18
+ const buildModelStudioProvider = buildQwenProvider;
19
+ //#endregion
20
+ export { buildModelStudioProvider, buildQwenOAuthProvider, buildQwenProvider };
package/dist/stream.js ADDED
@@ -0,0 +1,85 @@
1
+ import { normalizeProviderId } from "openclaw/plugin-sdk/provider-model-shared";
2
+ import { createPayloadPatchStreamWrapper, isOpenAICompatibleThinkingEnabled } from "openclaw/plugin-sdk/provider-stream-shared";
3
+ //#region extensions/qwen/stream.ts
4
+ function isQwenProviderId(providerId) {
5
+ const normalized = normalizeProviderId(providerId);
6
+ return normalized === "qwen" || normalized === "qwen-oauth" || normalized === "qwen-portal" || normalized === "qwen-cli" || normalized === "modelstudio" || normalized === "qwencloud" || normalized === "dashscope";
7
+ }
8
+ function isQwenOAuthProviderId(providerId) {
9
+ const normalized = normalizeProviderId(providerId);
10
+ return normalized === "qwen-oauth" || normalized === "qwen-portal" || normalized === "qwen-cli";
11
+ }
12
+ function normalizeQwenOAuthContent(content) {
13
+ if (typeof content === "string") return [{
14
+ type: "text",
15
+ text: content
16
+ }];
17
+ if (!Array.isArray(content)) return content;
18
+ const normalized = content.map((part) => {
19
+ if (typeof part === "string") return {
20
+ type: "text",
21
+ text: part
22
+ };
23
+ return part && typeof part === "object" ? part : void 0;
24
+ }).filter((part) => Boolean(part));
25
+ return normalized.length > 0 ? normalized : content;
26
+ }
27
+ function patchQwenOAuthPayload(payload) {
28
+ const messages = payload.messages;
29
+ if (!Array.isArray(messages)) return;
30
+ for (const message of messages) {
31
+ if (!message || typeof message !== "object") continue;
32
+ const record = message;
33
+ record.content = normalizeQwenOAuthContent(record.content);
34
+ if (record.role !== "system" || !Array.isArray(record.content) || record.content.length === 0) continue;
35
+ const last = record.content[record.content.length - 1];
36
+ if (last && typeof last === "object") last.cache_control = { type: "ephemeral" };
37
+ }
38
+ payload.vl_high_resolution_images = true;
39
+ }
40
+ function setQwenChatTemplateThinking(payload, enabled) {
41
+ const existing = payload.chat_template_kwargs;
42
+ if (existing && typeof existing === "object" && !Array.isArray(existing)) {
43
+ const next = {
44
+ ...existing,
45
+ enable_thinking: enabled
46
+ };
47
+ if (!Object.hasOwn(next, "preserve_thinking")) next.preserve_thinking = true;
48
+ payload.chat_template_kwargs = next;
49
+ return;
50
+ }
51
+ payload.chat_template_kwargs = {
52
+ enable_thinking: enabled,
53
+ preserve_thinking: true
54
+ };
55
+ }
56
+ function readQwenThinkingFormatFromModel(model) {
57
+ if (model.api !== "openai-completions") return;
58
+ const compat = model.compat && typeof model.compat === "object" ? model.compat : void 0;
59
+ return typeof compat?.thinkingFormat === "string" ? compat.thinkingFormat : void 0;
60
+ }
61
+ function createQwenThinkingWrapper(baseStreamFn, thinkingLevel, thinkingFormat) {
62
+ return createPayloadPatchStreamWrapper(baseStreamFn, ({ payload: payloadObj, model, options }) => {
63
+ const enableThinking = isOpenAICompatibleThinkingEnabled({
64
+ thinkingLevel,
65
+ options
66
+ });
67
+ if ((thinkingFormat ?? readQwenThinkingFormatFromModel(model)) === "qwen-chat-template") {
68
+ setQwenChatTemplateThinking(payloadObj, enableThinking);
69
+ delete payloadObj.enable_thinking;
70
+ } else payloadObj.enable_thinking = enableThinking;
71
+ delete payloadObj.reasoning_effort;
72
+ delete payloadObj.reasoningEffort;
73
+ delete payloadObj.reasoning;
74
+ }, { shouldPatch: ({ model }) => model.api === "openai-completions" && model.reasoning });
75
+ }
76
+ function wrapQwenProviderStream(ctx) {
77
+ if (!isQwenProviderId(ctx.provider) || ctx.model && ctx.model.api !== "openai-completions") return;
78
+ const streamFn = createQwenThinkingWrapper(ctx.streamFn, ctx.thinkingLevel, ctx.model ? readQwenThinkingFormatFromModel(ctx.model) : void 0);
79
+ if (!isQwenOAuthProviderId(ctx.provider)) return streamFn;
80
+ return createPayloadPatchStreamWrapper(streamFn, ({ payload, model }) => {
81
+ if (model.api === "openai-completions") patchQwenOAuthPayload(payload);
82
+ });
83
+ }
84
+ //#endregion
85
+ export { createQwenThinkingWrapper, wrapQwenProviderStream };
@@ -0,0 +1,76 @@
1
+ import "./models.js";
2
+ import { resolveProviderHttpRequestConfig } from "openclaw/plugin-sdk/provider-http";
3
+ import { isProviderApiKeyConfigured } from "openclaw/plugin-sdk/provider-auth";
4
+ import { resolveApiKeyForProvider } from "openclaw/plugin-sdk/provider-auth-runtime";
5
+ import { DASHSCOPE_WAN_VIDEO_CAPABILITIES, DASHSCOPE_WAN_VIDEO_MODELS, DEFAULT_DASHSCOPE_WAN_VIDEO_MODEL, DEFAULT_VIDEO_GENERATION_TIMEOUT_MS, runDashscopeVideoGenerationTask } from "openclaw/plugin-sdk/video-generation";
6
+ //#region extensions/qwen/video-generation-provider.ts
7
+ const DEFAULT_QWEN_VIDEO_BASE_URL = "https://dashscope-intl.aliyuncs.com";
8
+ const DEFAULT_QWEN_VIDEO_MODEL = DEFAULT_DASHSCOPE_WAN_VIDEO_MODEL;
9
+ function resolveQwenVideoBaseUrl(req) {
10
+ const direct = req.cfg?.models?.providers?.qwen?.baseUrl?.trim();
11
+ if (!direct) return DEFAULT_QWEN_VIDEO_BASE_URL;
12
+ try {
13
+ return new URL(direct).toString();
14
+ } catch {
15
+ return DEFAULT_QWEN_VIDEO_BASE_URL;
16
+ }
17
+ }
18
+ function resolveDashscopeAigcApiBaseUrl(baseUrl) {
19
+ try {
20
+ const url = new URL(baseUrl);
21
+ if (url.hostname === "coding-intl.dashscope.aliyuncs.com" || url.hostname === "coding.dashscope.aliyuncs.com" || url.hostname === "dashscope-intl.aliyuncs.com" || url.hostname === "dashscope.aliyuncs.com") return url.origin;
22
+ } catch {}
23
+ if (baseUrl.startsWith("https://dashscope.aliyuncs.com/compatible-mode/v1")) return "https://dashscope.aliyuncs.com";
24
+ if (baseUrl.startsWith("https://dashscope-intl.aliyuncs.com/compatible-mode/v1")) return DEFAULT_QWEN_VIDEO_BASE_URL;
25
+ return baseUrl.replace(/\/+$/u, "");
26
+ }
27
+ function buildQwenVideoGenerationProvider() {
28
+ return {
29
+ id: "qwen",
30
+ label: "Qwen Cloud",
31
+ defaultModel: DEFAULT_QWEN_VIDEO_MODEL,
32
+ models: [...DASHSCOPE_WAN_VIDEO_MODELS],
33
+ isConfigured: ({ agentDir }) => isProviderApiKeyConfigured({
34
+ provider: "qwen",
35
+ agentDir
36
+ }),
37
+ capabilities: DASHSCOPE_WAN_VIDEO_CAPABILITIES,
38
+ async generateVideo(req) {
39
+ const fetchFn = fetch;
40
+ const auth = await resolveApiKeyForProvider({
41
+ provider: "qwen",
42
+ cfg: req.cfg,
43
+ agentDir: req.agentDir,
44
+ store: req.authStore
45
+ });
46
+ if (!auth.apiKey) throw new Error("Qwen API key missing");
47
+ const { baseUrl, allowPrivateNetwork, headers, dispatcherPolicy } = resolveProviderHttpRequestConfig({
48
+ baseUrl: resolveQwenVideoBaseUrl(req),
49
+ defaultBaseUrl: DEFAULT_QWEN_VIDEO_BASE_URL,
50
+ defaultHeaders: {
51
+ Authorization: `Bearer ${auth.apiKey}`,
52
+ "Content-Type": "application/json",
53
+ "X-DashScope-Async": "enable"
54
+ },
55
+ provider: "qwen",
56
+ capability: "video",
57
+ transport: "http"
58
+ });
59
+ return await runDashscopeVideoGenerationTask({
60
+ providerLabel: "Qwen",
61
+ model: req.model?.trim() || DEFAULT_QWEN_VIDEO_MODEL,
62
+ req,
63
+ url: `${resolveDashscopeAigcApiBaseUrl(baseUrl)}/api/v1/services/aigc/video-generation/video-synthesis`,
64
+ headers,
65
+ baseUrl: resolveDashscopeAigcApiBaseUrl(baseUrl),
66
+ timeoutMs: req.timeoutMs,
67
+ fetchFn,
68
+ allowPrivateNetwork,
69
+ dispatcherPolicy,
70
+ defaultTimeoutMs: DEFAULT_VIDEO_GENERATION_TIMEOUT_MS
71
+ });
72
+ }
73
+ };
74
+ }
75
+ //#endregion
76
+ export { buildQwenVideoGenerationProvider };
@@ -0,0 +1,12 @@
1
+ {
2
+ "name": "@openclaw/qwen-provider",
3
+ "version": "2026.6.9-beta.1",
4
+ "lockfileVersion": 3,
5
+ "requires": true,
6
+ "packages": {
7
+ "": {
8
+ "name": "@openclaw/qwen-provider",
9
+ "version": "2026.6.9-beta.1"
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,325 @@
1
+ {
2
+ "id": "qwen",
3
+ "activation": {
4
+ "onStartup": false
5
+ },
6
+ "enabledByDefault": true,
7
+ "providers": ["qwen", "qwencloud", "modelstudio", "dashscope", "qwen-oauth", "qwen-portal", "qwen-cli"],
8
+ "providerAuthAliases": {
9
+ "qwen-portal": "qwen-oauth",
10
+ "qwen-cli": "qwen-oauth"
11
+ },
12
+ "providerEndpoints": [
13
+ {
14
+ "endpointClass": "modelstudio-native",
15
+ "baseUrls": [
16
+ "https://coding-intl.dashscope.aliyuncs.com/v1",
17
+ "https://coding.dashscope.aliyuncs.com/v1",
18
+ "https://dashscope.aliyuncs.com/compatible-mode/v1",
19
+ "https://dashscope-intl.aliyuncs.com/compatible-mode/v1"
20
+ ]
21
+ },
22
+ {
23
+ "endpointClass": "qwen-portal-native",
24
+ "baseUrls": ["https://portal.qwen.ai/v1"]
25
+ }
26
+ ],
27
+ "providerRequest": {
28
+ "providers": {
29
+ "qwen": {
30
+ "family": "modelstudio"
31
+ },
32
+ "qwencloud": {
33
+ "family": "modelstudio"
34
+ },
35
+ "modelstudio": {
36
+ "family": "modelstudio"
37
+ },
38
+ "dashscope": {
39
+ "family": "modelstudio"
40
+ },
41
+ "qwen-oauth": {
42
+ "family": "qwen-portal"
43
+ },
44
+ "qwen-portal": {
45
+ "family": "qwen-portal"
46
+ },
47
+ "qwen-cli": {
48
+ "family": "qwen-portal"
49
+ }
50
+ }
51
+ },
52
+ "modelCatalog": {
53
+ "aliases": {
54
+ "qwen-portal": {
55
+ "provider": "qwen-oauth"
56
+ },
57
+ "qwen-cli": {
58
+ "provider": "qwen-oauth"
59
+ }
60
+ },
61
+ "suppressions": [
62
+ {
63
+ "provider": "qwen",
64
+ "model": "qwen3.6-plus",
65
+ "reason": "qwen3.6-plus is not supported on the Qwen Coding Plan endpoint; use a Standard pay-as-you-go Qwen endpoint or choose qwen/qwen3.5-plus.",
66
+ "when": {
67
+ "baseUrlHosts": ["coding.dashscope.aliyuncs.com", "coding-intl.dashscope.aliyuncs.com"],
68
+ "providerConfigApiIn": ["qwen", "modelstudio"]
69
+ }
70
+ },
71
+ {
72
+ "provider": "modelstudio",
73
+ "model": "qwen3.6-plus",
74
+ "reason": "qwen3.6-plus is not supported on the Qwen Coding Plan endpoint; use a Standard pay-as-you-go Qwen endpoint or choose qwen/qwen3.5-plus.",
75
+ "when": {
76
+ "baseUrlHosts": ["coding.dashscope.aliyuncs.com", "coding-intl.dashscope.aliyuncs.com"],
77
+ "providerConfigApiIn": ["qwen", "modelstudio"]
78
+ }
79
+ }
80
+ ],
81
+ "providers": {
82
+ "qwen-oauth": {
83
+ "baseUrl": "https://portal.qwen.ai/v1",
84
+ "api": "openai-completions",
85
+ "models": [
86
+ {
87
+ "id": "qwen3.5-plus",
88
+ "name": "qwen3.5-plus",
89
+ "reasoning": false,
90
+ "input": ["text", "image"],
91
+ "cost": {
92
+ "input": 0,
93
+ "output": 0,
94
+ "cacheRead": 0,
95
+ "cacheWrite": 0
96
+ },
97
+ "contextWindow": 1000000,
98
+ "maxTokens": 65536
99
+ },
100
+ {
101
+ "id": "qwen3.6-plus",
102
+ "name": "qwen3.6-plus",
103
+ "reasoning": false,
104
+ "input": ["text", "image"],
105
+ "cost": {
106
+ "input": 0,
107
+ "output": 0,
108
+ "cacheRead": 0,
109
+ "cacheWrite": 0
110
+ },
111
+ "contextWindow": 1000000,
112
+ "maxTokens": 65536
113
+ },
114
+ {
115
+ "id": "qwen3-max-2026-01-23",
116
+ "name": "qwen3-max-2026-01-23",
117
+ "reasoning": false,
118
+ "input": ["text"],
119
+ "cost": {
120
+ "input": 0,
121
+ "output": 0,
122
+ "cacheRead": 0,
123
+ "cacheWrite": 0
124
+ },
125
+ "contextWindow": 262144,
126
+ "maxTokens": 65536
127
+ },
128
+ {
129
+ "id": "qwen3-coder-next",
130
+ "name": "qwen3-coder-next",
131
+ "reasoning": false,
132
+ "input": ["text"],
133
+ "cost": {
134
+ "input": 0,
135
+ "output": 0,
136
+ "cacheRead": 0,
137
+ "cacheWrite": 0
138
+ },
139
+ "contextWindow": 262144,
140
+ "maxTokens": 65536
141
+ },
142
+ {
143
+ "id": "qwen3-coder-plus",
144
+ "name": "qwen3-coder-plus",
145
+ "reasoning": false,
146
+ "input": ["text"],
147
+ "cost": {
148
+ "input": 0,
149
+ "output": 0,
150
+ "cacheRead": 0,
151
+ "cacheWrite": 0
152
+ },
153
+ "contextWindow": 1000000,
154
+ "maxTokens": 65536
155
+ },
156
+ {
157
+ "id": "MiniMax-M2.5",
158
+ "name": "MiniMax-M2.5",
159
+ "reasoning": true,
160
+ "input": ["text"],
161
+ "cost": {
162
+ "input": 0,
163
+ "output": 0,
164
+ "cacheRead": 0,
165
+ "cacheWrite": 0
166
+ },
167
+ "contextWindow": 1000000,
168
+ "maxTokens": 65536
169
+ },
170
+ {
171
+ "id": "glm-5",
172
+ "name": "glm-5",
173
+ "reasoning": false,
174
+ "input": ["text"],
175
+ "cost": {
176
+ "input": 0,
177
+ "output": 0,
178
+ "cacheRead": 0,
179
+ "cacheWrite": 0
180
+ },
181
+ "contextWindow": 202752,
182
+ "maxTokens": 65536
183
+ },
184
+ {
185
+ "id": "glm-4.7",
186
+ "name": "glm-4.7",
187
+ "reasoning": false,
188
+ "input": ["text"],
189
+ "cost": {
190
+ "input": 0,
191
+ "output": 0,
192
+ "cacheRead": 0,
193
+ "cacheWrite": 0
194
+ },
195
+ "contextWindow": 202752,
196
+ "maxTokens": 65536
197
+ },
198
+ {
199
+ "id": "kimi-k2.5",
200
+ "name": "kimi-k2.5",
201
+ "reasoning": false,
202
+ "input": ["text", "image"],
203
+ "cost": {
204
+ "input": 0,
205
+ "output": 0,
206
+ "cacheRead": 0,
207
+ "cacheWrite": 0
208
+ },
209
+ "contextWindow": 262144,
210
+ "maxTokens": 65536
211
+ }
212
+ ]
213
+ }
214
+ }
215
+ },
216
+ "contracts": {
217
+ "mediaUnderstandingProviders": ["qwen"],
218
+ "videoGenerationProviders": ["qwen"]
219
+ },
220
+ "mediaUnderstandingProviderMetadata": {
221
+ "qwen": {
222
+ "capabilities": ["image", "video"],
223
+ "defaultModels": {
224
+ "image": "qwen-vl-max-latest",
225
+ "video": "qwen-vl-max-latest"
226
+ },
227
+ "autoPriority": {
228
+ "video": 15
229
+ }
230
+ }
231
+ },
232
+ "setup": {
233
+ "providers": [
234
+ {
235
+ "id": "qwen",
236
+ "envVars": ["QWEN_API_KEY", "MODELSTUDIO_API_KEY", "DASHSCOPE_API_KEY"]
237
+ },
238
+ {
239
+ "id": "qwen-oauth",
240
+ "envVars": ["QWEN_API_KEY"]
241
+ }
242
+ ]
243
+ },
244
+ "providerAuthChoices": [
245
+ {
246
+ "provider": "qwen",
247
+ "method": "standard-api-key-cn",
248
+ "choiceId": "qwen-standard-api-key-cn",
249
+ "deprecatedChoiceIds": ["modelstudio-standard-api-key-cn"],
250
+ "choiceLabel": "Standard API Key for China (pay-as-you-go)",
251
+ "choiceHint": "Endpoint: dashscope.aliyuncs.com",
252
+ "groupId": "qwen",
253
+ "groupLabel": "Qwen Cloud",
254
+ "groupHint": "Standard / Coding Plan (CN / Global) + multimodal roadmap",
255
+ "optionKey": "modelstudioStandardApiKeyCn",
256
+ "cliFlag": "--modelstudio-standard-api-key-cn",
257
+ "cliOption": "--modelstudio-standard-api-key-cn <key>",
258
+ "cliDescription": "Qwen Cloud standard API key (China)"
259
+ },
260
+ {
261
+ "provider": "qwen",
262
+ "method": "standard-api-key",
263
+ "choiceId": "qwen-standard-api-key",
264
+ "deprecatedChoiceIds": ["modelstudio-standard-api-key"],
265
+ "choiceLabel": "Standard API Key for Global/Intl (pay-as-you-go)",
266
+ "choiceHint": "Endpoint: dashscope-intl.aliyuncs.com",
267
+ "groupId": "qwen",
268
+ "groupLabel": "Qwen Cloud",
269
+ "groupHint": "Standard / Coding Plan (CN / Global) + multimodal roadmap",
270
+ "optionKey": "modelstudioStandardApiKey",
271
+ "cliFlag": "--modelstudio-standard-api-key",
272
+ "cliOption": "--modelstudio-standard-api-key <key>",
273
+ "cliDescription": "Qwen Cloud standard API key (Global/Intl)"
274
+ },
275
+ {
276
+ "provider": "qwen",
277
+ "method": "api-key-cn",
278
+ "choiceId": "qwen-api-key-cn",
279
+ "deprecatedChoiceIds": ["modelstudio-api-key-cn"],
280
+ "choiceLabel": "Coding Plan API Key for China (subscription)",
281
+ "choiceHint": "Endpoint: coding.dashscope.aliyuncs.com",
282
+ "groupId": "qwen",
283
+ "groupLabel": "Qwen Cloud",
284
+ "groupHint": "Standard / Coding Plan (CN / Global) + multimodal roadmap",
285
+ "optionKey": "modelstudioApiKeyCn",
286
+ "cliFlag": "--modelstudio-api-key-cn",
287
+ "cliOption": "--modelstudio-api-key-cn <key>",
288
+ "cliDescription": "Qwen Cloud Coding Plan API key (China)"
289
+ },
290
+ {
291
+ "provider": "qwen",
292
+ "method": "api-key",
293
+ "choiceId": "qwen-api-key",
294
+ "deprecatedChoiceIds": ["modelstudio-api-key"],
295
+ "choiceLabel": "Coding Plan API Key for Global/Intl (subscription)",
296
+ "choiceHint": "Endpoint: coding-intl.dashscope.aliyuncs.com",
297
+ "groupId": "qwen",
298
+ "groupLabel": "Qwen Cloud",
299
+ "groupHint": "Standard / Coding Plan (CN / Global) + multimodal roadmap",
300
+ "optionKey": "modelstudioApiKey",
301
+ "cliFlag": "--modelstudio-api-key",
302
+ "cliOption": "--modelstudio-api-key <key>",
303
+ "cliDescription": "Qwen Cloud Coding Plan API key (Global/Intl)"
304
+ },
305
+ {
306
+ "provider": "qwen-oauth",
307
+ "method": "api-key",
308
+ "choiceId": "qwen-oauth",
309
+ "choiceLabel": "Qwen OAuth",
310
+ "choiceHint": "Portal token for portal.qwen.ai",
311
+ "groupId": "qwen",
312
+ "groupLabel": "Qwen Cloud",
313
+ "groupHint": "Standard / Coding Plan / OAuth",
314
+ "optionKey": "qwenOauthToken",
315
+ "cliFlag": "--qwen-oauth-token",
316
+ "cliOption": "--qwen-oauth-token <token>",
317
+ "cliDescription": "Qwen OAuth token"
318
+ }
319
+ ],
320
+ "configSchema": {
321
+ "type": "object",
322
+ "additionalProperties": false,
323
+ "properties": {}
324
+ }
325
+ }
package/package.json CHANGED
@@ -1,14 +1,50 @@
1
1
  {
2
2
  "name": "@openclaw/qwen-provider",
3
- "version": "0.0.0",
4
- "description": "Reserved package name for an official OpenClaw plugin.",
5
- "license": "MIT",
3
+ "version": "2026.6.9-beta.1",
4
+ "description": "OpenClaw Qwen Cloud provider plugin.",
6
5
  "repository": {
7
6
  "type": "git",
8
- "url": "git+https://github.com/openclaw/openclaw.git"
7
+ "url": "https://github.com/openclaw/openclaw"
9
8
  },
10
- "publishConfig": {
11
- "access": "public",
12
- "tag": "placeholder"
13
- }
9
+ "type": "module",
10
+ "openclaw": {
11
+ "extensions": [
12
+ "./index.ts"
13
+ ],
14
+ "install": {
15
+ "clawhubSpec": "clawhub:@openclaw/qwen-provider",
16
+ "npmSpec": "@openclaw/qwen-provider",
17
+ "defaultChoice": "npm",
18
+ "minHostVersion": ">=2026.6.8"
19
+ },
20
+ "compat": {
21
+ "pluginApi": ">=2026.6.9-beta.1"
22
+ },
23
+ "build": {
24
+ "openclawVersion": "2026.6.9-beta.1",
25
+ "bundledDist": false
26
+ },
27
+ "release": {
28
+ "publishToClawHub": true,
29
+ "publishToNpm": true
30
+ },
31
+ "runtimeExtensions": [
32
+ "./dist/index.js"
33
+ ]
34
+ },
35
+ "files": [
36
+ "dist/**",
37
+ "openclaw.plugin.json",
38
+ "npm-shrinkwrap.json",
39
+ "README.md"
40
+ ],
41
+ "peerDependencies": {
42
+ "openclaw": ">=2026.6.9-beta.1"
43
+ },
44
+ "peerDependenciesMeta": {
45
+ "openclaw": {
46
+ "optional": true
47
+ }
48
+ },
49
+ "bundledDependencies": []
14
50
  }