@zhivex-ai/qwen 0.7.7 → 0.8.0
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 +140 -37
- package/dist/index.d.ts +23 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +801 -278
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# @zhivex-ai/qwen
|
|
2
2
|
|
|
3
|
-
Qwen adapter for Zhivex AI SDK.
|
|
3
|
+
Qwen and Alibaba Cloud Model Studio adapter for Zhivex AI SDK.
|
|
4
4
|
|
|
5
5
|
## Install
|
|
6
6
|
|
|
@@ -8,14 +8,60 @@ Qwen adapter for Zhivex AI SDK.
|
|
|
8
8
|
bun add @zhivex-ai/qwen
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
##
|
|
11
|
+
## Configure
|
|
12
12
|
|
|
13
|
-
|
|
13
|
+
```ts
|
|
14
|
+
import { createQwen } from "@zhivex-ai/qwen";
|
|
15
|
+
|
|
16
|
+
const qwen = createQwen({
|
|
17
|
+
apiKey: process.env.DASHSCOPE_API_KEY
|
|
18
|
+
});
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
For Alibaba Cloud Model Studio workspace endpoints, configure the workspace once and the adapter derives the compatible HTTP, native task, and realtime URLs:
|
|
22
|
+
|
|
23
|
+
```ts
|
|
24
|
+
const qwen = createQwen({
|
|
25
|
+
apiKey: process.env.DASHSCOPE_API_KEY,
|
|
26
|
+
workspaceId: process.env.QWEN_WORKSPACE_ID,
|
|
27
|
+
region: "singapore"
|
|
28
|
+
});
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Supported region values are `singapore`, `beijing`, `hong-kong`, `tokyo`, `frankfurt`, and `virginia`. `baseURL`, `taskBaseURL`, and `realtimeURL` remain available for private gateways or an explicit regional endpoint.
|
|
32
|
+
|
|
33
|
+
## Text, tools, and structured output
|
|
34
|
+
|
|
35
|
+
The default `apiMode: "auto"` selects the protocol required by the request:
|
|
36
|
+
|
|
37
|
+
- Responses for hosted tools, Qwen OCR file URLs, and `previous_response_id` continuation.
|
|
38
|
+
- Chat Completions for structured output, audio input, `maxTokens`, or `reasoning.budgetTokens`.
|
|
39
|
+
- Either path for ordinary text and local function tools; automatic mode prefers Responses.
|
|
40
|
+
|
|
41
|
+
Use `providerOptions: { apiMode: "responses" }` or `{ apiMode: "chat" }` only when you need to force a compatible path. Unsupported combinations fail before the network request instead of silently dropping fields.
|
|
42
|
+
|
|
43
|
+
`qwen3.5-omni-plus` and `qwen3.5-omni-flash` are streaming-only Chat Completions models. Use `streamText()` for them; the adapter rejects `generateText()`, Responses-only hosted tools, file inputs, and reasoning controls that those models do not support. Text output is selected by default with `modalities: ["text"]`, while an explicit compatible `modalities` option is preserved.
|
|
44
|
+
|
|
45
|
+
Qwen Chat Completions supports JSON-object mode but does not currently enforce a JSON Schema natively. `generateObject()` therefore sends JSON mode plus a schema system prompt and validates the result locally:
|
|
46
|
+
|
|
47
|
+
```ts
|
|
48
|
+
import { generateObject } from "@zhivex-ai/sdk";
|
|
49
|
+
import { z } from "zod";
|
|
50
|
+
|
|
51
|
+
const result = await generateObject({
|
|
52
|
+
model: qwen("qwen3.7-plus"),
|
|
53
|
+
prompt: "Return the city and temperature.",
|
|
54
|
+
schema: z.object({ city: z.string(), temperature: z.number() })
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
Responses reasoning maps shared `effort` to `reasoning.effort` (`low` becomes Qwen `minimal`). Chat reasoning maps to `enable_thinking`; `budgetTokens` maps to `thinking_budget`.
|
|
59
|
+
|
|
60
|
+
### Hosted tools
|
|
14
61
|
|
|
15
62
|
```ts
|
|
16
63
|
import { generateText } from "@zhivex-ai/sdk";
|
|
17
64
|
import {
|
|
18
|
-
createQwen,
|
|
19
65
|
qwenCodeInterpreterTool,
|
|
20
66
|
qwenFileSearchTool,
|
|
21
67
|
qwenMcpTool,
|
|
@@ -23,10 +69,6 @@ import {
|
|
|
23
69
|
qwenWebSearchTool
|
|
24
70
|
} from "@zhivex-ai/qwen";
|
|
25
71
|
|
|
26
|
-
const qwen = createQwen({
|
|
27
|
-
apiKey: process.env.DASHSCOPE_API_KEY
|
|
28
|
-
});
|
|
29
|
-
|
|
30
72
|
const result = await generateText({
|
|
31
73
|
model: qwen("qwen3.7-plus"),
|
|
32
74
|
prompt: "Search current docs, extract the relevant page, and validate a calculation.",
|
|
@@ -34,7 +76,7 @@ const result = await generateText({
|
|
|
34
76
|
search: qwenWebSearchTool(),
|
|
35
77
|
extract: qwenWebExtractorTool(),
|
|
36
78
|
code: qwenCodeInterpreterTool(),
|
|
37
|
-
files: qwenFileSearchTool({ vector_store_ids: ["
|
|
79
|
+
files: qwenFileSearchTool({ vector_store_ids: ["existing_knowledge_base_id"] }),
|
|
38
80
|
maps: qwenMcpTool({
|
|
39
81
|
server_label: "amap-maps",
|
|
40
82
|
server_protocol: "sse",
|
|
@@ -47,56 +89,117 @@ const result = await generateText({
|
|
|
47
89
|
console.log(result.text);
|
|
48
90
|
```
|
|
49
91
|
|
|
50
|
-
|
|
92
|
+
`qwenFileSearchTool()` consumes an existing Alibaba Cloud knowledge-base/vector-store identifier. The package intentionally does not expose invented file-search-store CRUD endpoints; DashScope Files remains available for extraction and batch jobs.
|
|
51
93
|
|
|
52
|
-
##
|
|
94
|
+
## Files and batch
|
|
53
95
|
|
|
54
|
-
|
|
96
|
+
Batch inference requires a JSONL file uploaded with `purpose: "batch"`:
|
|
55
97
|
|
|
56
98
|
```ts
|
|
57
|
-
import {
|
|
58
|
-
createBatch,
|
|
59
|
-
generateImage,
|
|
60
|
-
generateSpeech,
|
|
61
|
-
transcribeAudio,
|
|
62
|
-
uploadFile
|
|
63
|
-
} from "@zhivex-ai/sdk";
|
|
64
|
-
import { createQwen } from "@zhivex-ai/qwen";
|
|
65
|
-
|
|
66
|
-
const qwen = createQwen({
|
|
67
|
-
apiKey: process.env.DASHSCOPE_API_KEY
|
|
68
|
-
});
|
|
99
|
+
import { createBatch, uploadFile } from "@zhivex-ai/sdk";
|
|
69
100
|
|
|
70
101
|
const file = await uploadFile({
|
|
71
102
|
provider: qwen,
|
|
72
|
-
data:
|
|
73
|
-
mediaType: "
|
|
74
|
-
filename: "
|
|
103
|
+
data: batchJsonl,
|
|
104
|
+
mediaType: "application/jsonl",
|
|
105
|
+
filename: "requests.jsonl",
|
|
106
|
+
providerOptions: { purpose: "batch" }
|
|
75
107
|
});
|
|
76
108
|
|
|
77
|
-
await createBatch({
|
|
109
|
+
const batch = await createBatch({
|
|
78
110
|
provider: qwen,
|
|
79
111
|
modelId: "qwen3.7-plus",
|
|
80
112
|
fileName: file.name
|
|
81
113
|
});
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
## Speech and generative media
|
|
117
|
+
|
|
118
|
+
```ts
|
|
119
|
+
import {
|
|
120
|
+
generateImage,
|
|
121
|
+
generateSpeech,
|
|
122
|
+
generateVideo,
|
|
123
|
+
transcribeAudio
|
|
124
|
+
} from "@zhivex-ai/sdk";
|
|
82
125
|
|
|
83
|
-
await transcribeAudio({
|
|
84
|
-
model: qwen.transcriptionModel("
|
|
85
|
-
audio: { data:
|
|
126
|
+
const transcript = await transcribeAudio({
|
|
127
|
+
model: qwen.transcriptionModel("qwen3-asr-flash"),
|
|
128
|
+
audio: { data: audioBytes, mediaType: "audio/wav" }
|
|
86
129
|
});
|
|
87
130
|
|
|
88
|
-
await generateSpeech({
|
|
89
|
-
model: qwen.speechModel("
|
|
90
|
-
input: "Hello from Qwen."
|
|
131
|
+
const speech = await generateSpeech({
|
|
132
|
+
model: qwen.speechModel("qwen3-tts-flash"),
|
|
133
|
+
input: "Hello from Qwen.",
|
|
134
|
+
voice: "Cherry",
|
|
135
|
+
providerOptions: { language_type: "English" }
|
|
91
136
|
});
|
|
92
137
|
|
|
93
|
-
await generateImage({
|
|
138
|
+
const image = await generateImage({
|
|
94
139
|
model: qwen.imageGenerationModel("qwen-image-2.0-pro"),
|
|
95
|
-
prompt: "A clean product icon"
|
|
140
|
+
prompt: "A clean product icon",
|
|
141
|
+
size: "1024*1024"
|
|
96
142
|
});
|
|
143
|
+
|
|
144
|
+
const video = await generateVideo({
|
|
145
|
+
model: qwen.videoGenerationModel("wan2.7-t2v"),
|
|
146
|
+
prompt: "A clean product icon rotating slowly",
|
|
147
|
+
providerOptions: { resolution: "720P", watermark: false }
|
|
148
|
+
});
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Speech responses are bounded by `createQwen({ responseLimits })`. The default decoded speech limit is 16 MiB, base64 size is checked before decoding, and encoded audio is removed from `SpeechResult.rawResponse` after decoding to avoid retaining two copies.
|
|
152
|
+
|
|
153
|
+
Downloaded speech URLs are also protected against server-side request forgery. By default, the adapter accepts the HTTP(S) Alibaba OSS hosts used by Qwen TTS, follows at most three redirects manually, and validates every redirect target without forwarding the Qwen API key. Private gateways can provide an explicit `speechAudioURLValidator`; `speechAudioMaxRedirects` can be set from 0 through 10.
|
|
154
|
+
|
|
155
|
+
## Multimodal embeddings and reranking
|
|
156
|
+
|
|
157
|
+
```ts
|
|
158
|
+
const embeddings = await qwen
|
|
159
|
+
.multimodalEmbeddingModel("qwen3-vl-embedding")
|
|
160
|
+
.embed({
|
|
161
|
+
values: [
|
|
162
|
+
"product description",
|
|
163
|
+
{ uri: "https://example.com/product.png", mediaType: "image/png" }
|
|
164
|
+
]
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
const ranked = await qwen.rerankModel("qwen3-rerank").rerank({
|
|
168
|
+
query: "Qwen SDK support",
|
|
169
|
+
documents: ["unrelated", "Zhivex supports Qwen."],
|
|
170
|
+
topN: 1
|
|
171
|
+
});
|
|
172
|
+
```
|
|
173
|
+
|
|
174
|
+
`qwen3-vl-rerank` and other native multimodal rerank models also accept `MediaInput` query and document values.
|
|
175
|
+
|
|
176
|
+
## Realtime
|
|
177
|
+
|
|
178
|
+
```ts
|
|
179
|
+
const session = await qwen
|
|
180
|
+
.realtimeModel("qwen3.5-omni-plus-realtime")
|
|
181
|
+
.connect({
|
|
182
|
+
instructions: "Be concise.",
|
|
183
|
+
turnDetection: { type: "server_vad" }
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
await session.sendText("Hello");
|
|
187
|
+
await session.sendMedia({ data: jpegBytes, mediaType: "image/jpeg" });
|
|
188
|
+
```
|
|
189
|
+
|
|
190
|
+
The realtime adapter maps text, audio, transcripts, function calls, response completion, and session completion into the shared `RealtimeEvent` contract. JPEG image frames are supported by Qwen Omni realtime; browser-token minting is not exposed.
|
|
191
|
+
|
|
192
|
+
## Current catalog coverage
|
|
193
|
+
|
|
194
|
+
The default catalog includes current text and multimodal Qwen families plus the specialized IDs wired above: `qwen3.7-plus`, `qwen3.7-max`, `qwen3.6-flash`, `qwen3.5-omni-plus`, `qwen3.5-omni-plus-realtime`, `qwen3.5-ocr`, `qwen3-vl-embedding`, `qwen3-rerank`, `qwen3-asr-flash`, `qwen3-tts-flash`, `qwen-image-2.0-pro`, and `wan2.7-t2v`.
|
|
195
|
+
|
|
196
|
+
Run opt-in live coverage with:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
QWEN_EXTENDED_INTEGRATION=1 bun run test:integration:qwen
|
|
97
200
|
```
|
|
98
201
|
|
|
99
|
-
|
|
202
|
+
Set only the surfaces you want to exercise: `QWEN_MULTIMODAL_EMBEDDING_MODEL`, `QWEN_MULTIMODAL_IMAGE_URL`, `QWEN_RERANK_MODEL`, `QWEN_ASR_MODEL`, `QWEN_ASR_AUDIO_URL`, `QWEN_TTS_MODEL`, `QWEN_IMAGE_MODEL`, `QWEN_VIDEO_MODEL`, and `QWEN_REALTIME_MODEL`. Workspace and endpoint overrides use `QWEN_WORKSPACE_ID`, `QWEN_REGION`, `QWEN_BASE_URL`, `QWEN_TASK_BASE_URL`, and `QWEN_REALTIME_URL`.
|
|
100
203
|
|
|
101
204
|
Repository and full documentation:
|
|
102
205
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,14 +1,20 @@
|
|
|
1
|
-
import { type CallableProviderAdapter, type EmbeddingModel, type JsonValue, type PredictionOperation, type ProviderAdapter, type RealtimeConnectionFactory } from "@zhivex-ai/core";
|
|
1
|
+
import { type AudioResponseLimits, type CallableProviderAdapter, type EmbedInput, type EmbeddingModel, type EmbedResult, type JsonValue, type MediaInput, type PredictionOperation, type ProviderAdapter, type RealtimeConnectionFactory } from "@zhivex-ai/core";
|
|
2
2
|
export interface QwenProviderOptions {
|
|
3
3
|
apiKey?: string;
|
|
4
|
+
workspaceId?: string;
|
|
5
|
+
region?: QwenRegion;
|
|
4
6
|
baseURL?: string;
|
|
5
7
|
taskBaseURL?: string;
|
|
6
8
|
realtimeURL?: string;
|
|
7
9
|
realtimeConnectionFactory?: RealtimeConnectionFactory;
|
|
8
10
|
fetch?: typeof globalThis.fetch;
|
|
11
|
+
responseLimits?: AudioResponseLimits;
|
|
12
|
+
speechAudioURLValidator?: QwenSpeechAudioURLValidator;
|
|
13
|
+
speechAudioMaxRedirects?: number;
|
|
9
14
|
}
|
|
15
|
+
export type QwenSpeechAudioURLValidator = (url: URL) => boolean | Promise<boolean>;
|
|
10
16
|
export interface QwenLanguageModelOptions {
|
|
11
|
-
apiMode?: "responses" | "chat";
|
|
17
|
+
apiMode?: "auto" | "responses" | "chat";
|
|
12
18
|
conversation?: string;
|
|
13
19
|
instructions?: string;
|
|
14
20
|
"x-dashscope-session-cache"?: "enable" | "disable";
|
|
@@ -28,9 +34,11 @@ export interface QwenLanguageModelOptions {
|
|
|
28
34
|
};
|
|
29
35
|
[key: string]: unknown;
|
|
30
36
|
}
|
|
37
|
+
export type QwenRegion = "singapore" | "beijing" | "hong-kong" | "tokyo" | "frankfurt" | "virginia";
|
|
38
|
+
export type QwenRerankValue = string | MediaInput;
|
|
31
39
|
export interface QwenRerankInput {
|
|
32
|
-
query:
|
|
33
|
-
documents:
|
|
40
|
+
query: QwenRerankValue;
|
|
41
|
+
documents: QwenRerankValue[];
|
|
34
42
|
topN?: number;
|
|
35
43
|
providerOptions?: Record<string, unknown>;
|
|
36
44
|
abortSignal?: AbortSignal;
|
|
@@ -41,7 +49,7 @@ export interface QwenRerankInput {
|
|
|
41
49
|
export interface QwenRerankResult {
|
|
42
50
|
results: Array<{
|
|
43
51
|
index: number;
|
|
44
|
-
document:
|
|
52
|
+
document: QwenRerankValue;
|
|
45
53
|
relevanceScore: number;
|
|
46
54
|
providerMetadata?: Record<string, unknown>;
|
|
47
55
|
}>;
|
|
@@ -52,6 +60,15 @@ export interface QwenRerankModel {
|
|
|
52
60
|
readonly modelId: string;
|
|
53
61
|
rerank(input: QwenRerankInput): Promise<QwenRerankResult>;
|
|
54
62
|
}
|
|
63
|
+
export interface QwenMultimodalEmbeddingModel extends EmbeddingModel {
|
|
64
|
+
embed(input: EmbedInput & {
|
|
65
|
+
providerOptions?: Record<string, unknown>;
|
|
66
|
+
abortSignal?: AbortSignal;
|
|
67
|
+
timeoutMs?: number;
|
|
68
|
+
maxRetries?: number;
|
|
69
|
+
retryBackoffMs?: number;
|
|
70
|
+
}): Promise<EmbedResult>;
|
|
71
|
+
}
|
|
55
72
|
export interface QwenTasksClient {
|
|
56
73
|
get(input: {
|
|
57
74
|
name: string;
|
|
@@ -71,7 +88,7 @@ export interface QwenTasksClient {
|
|
|
71
88
|
export type QwenProvider = CallableProviderAdapter & ProviderAdapter & {
|
|
72
89
|
rawFetch: typeof globalThis.fetch;
|
|
73
90
|
rerankModel(modelId: string): QwenRerankModel;
|
|
74
|
-
multimodalEmbeddingModel(modelId: string):
|
|
91
|
+
multimodalEmbeddingModel(modelId: string): QwenMultimodalEmbeddingModel;
|
|
75
92
|
tasks: QwenTasksClient;
|
|
76
93
|
};
|
|
77
94
|
export declare const createQwen: (options?: QwenProviderOptions) => QwenProvider;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|