@agentor/dashscope 0.0.0 → 0.0.2

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/dist/index.mjs CHANGED
@@ -1,23 +1,287 @@
1
+ import { OpenAICompatibleEmbeddingModel } from "@ai-sdk/openai-compatible";
2
+ import { combineHeaders, convertToBase64, createEventSourceResponseHandler, createJsonErrorResponseHandler, createJsonResponseHandler, createProviderToolFactoryWithOutputSchema, delay, generateId, getFromApi, isParsableJson, lazySchema, parseProviderOptions, postJsonToApi, zodSchema } from "@ai-sdk/provider-utils";
1
3
  import { z } from "zod/v4";
2
- import { combineHeaders, convertToBase64, createEventSourceResponseHandler, createJsonErrorResponseHandler, createJsonResponseHandler, createProviderToolFactoryWithOutputSchema, generateId, isParsableJson, lazySchema, parseProviderOptions, postJsonToApi, zodSchema } from "@ai-sdk/provider-utils";
3
- import { mapOpenAICompatibleFinishReason, prepareTools } from "@ai-sdk/openai-compatible/internal";
4
- //#region src/types.ts
5
- const DASHSCOPE_REGION_BASE_URLS = {
6
- beijing: {
7
- baseURL: "https://dashscope.aliyuncs.com/compatible-mode/v1",
8
- videoBaseURL: "https://dashscope.aliyuncs.com"
9
- },
10
- singapore: {
11
- baseURL: "https://dashscope-intl.aliyuncs.com/compatible-mode/v1",
12
- videoBaseURL: "https://dashscope-intl.aliyuncs.com"
13
- },
14
- us: {
15
- baseURL: "https://dashscope-us.aliyuncs.com/compatible-mode/v1",
16
- videoBaseURL: "https://dashscope-us.aliyuncs.com"
17
- },
18
- germany: {
19
- baseURL: "https://{workspaceId}.eu-central-1.maas.aliyuncs.com/compatible-mode/v1",
20
- videoBaseURL: "https://{workspaceId}.eu-central-1.maas.aliyuncs.com"
4
+ import { AISDKError } from "@ai-sdk/provider";
5
+ import { convertOpenAICompatibleChatUsage, getResponseMetadata, mapOpenAICompatibleFinishReason, prepareTools } from "@ai-sdk/openai-compatible/internal";
6
+ //#region src/embedding.ts
7
+ var DashScopeEmbeddingModel = class extends OpenAICompatibleEmbeddingModel {
8
+ constructor(modelId, config) {
9
+ super(modelId, {
10
+ provider: config.provider,
11
+ url: () => `${config.baseURL}/compatible-mode/v1/embeddings`,
12
+ headers: config.headers,
13
+ fetch: config.fetch
14
+ });
15
+ }
16
+ };
17
+ const failedResponseHandler = createJsonErrorResponseHandler({
18
+ errorSchema: zodSchema(z.object({ error: z.object({
19
+ message: z.string(),
20
+ code: z.string().nullish(),
21
+ type: z.string().nullish()
22
+ }) })),
23
+ errorToMessage: (data) => data.error.message
24
+ });
25
+ const nativeFailedHandler = createJsonErrorResponseHandler({
26
+ errorSchema: zodSchema(z.object({
27
+ code: z.string().nullish(),
28
+ message: z.string(),
29
+ request_id: z.string().nullish()
30
+ })),
31
+ errorToMessage: (data) => data.message
32
+ });
33
+ function convertResponsesUsage(usage) {
34
+ if (!usage) return {
35
+ inputTokens: {
36
+ total: 0,
37
+ noCache: void 0,
38
+ cacheRead: void 0,
39
+ cacheWrite: void 0
40
+ },
41
+ outputTokens: {
42
+ total: 0,
43
+ text: void 0,
44
+ reasoning: void 0
45
+ }
46
+ };
47
+ return {
48
+ inputTokens: {
49
+ total: usage.input_tokens ?? 0,
50
+ noCache: void 0,
51
+ cacheRead: usage.input_tokens_details?.cached_tokens ?? void 0,
52
+ cacheWrite: void 0
53
+ },
54
+ outputTokens: {
55
+ total: usage.output_tokens ?? 0,
56
+ text: void 0,
57
+ reasoning: usage.output_tokens_details?.reasoning_tokens ?? void 0
58
+ },
59
+ raw: usage
60
+ };
61
+ }
62
+ function uint8ArrayToBase64(data) {
63
+ let binary = "";
64
+ for (let i = 0; i < data.length; i++) binary += String.fromCharCode(data[i]);
65
+ return btoa(binary);
66
+ }
67
+ //#endregion
68
+ //#region src/image.ts
69
+ const imageOptionsSchema = z.object({
70
+ size: z.string().optional(),
71
+ negativePrompt: z.string().optional(),
72
+ promptExtend: z.boolean().optional(),
73
+ watermark: z.boolean().optional(),
74
+ n: z.number().optional()
75
+ });
76
+ const imageResponseSchema = zodSchema(z.object({
77
+ output: z.object({ choices: z.array(z.object({ message: z.object({ content: z.array(z.object({ image: z.string().optional() })) }) })).optional() }).nullish(),
78
+ usage: z.object({
79
+ image_count: z.number().optional(),
80
+ width: z.number().optional(),
81
+ height: z.number().optional()
82
+ }).nullish(),
83
+ request_id: z.string().nullish()
84
+ }));
85
+ var DashScopeImageModel = class {
86
+ specificationVersion = "v3";
87
+ modelId;
88
+ config;
89
+ constructor(modelId, config) {
90
+ this.modelId = modelId;
91
+ this.config = config;
92
+ }
93
+ get provider() {
94
+ return this.config.provider;
95
+ }
96
+ get maxImagesPerCall() {
97
+ return 1;
98
+ }
99
+ async doGenerate(options) {
100
+ const warnings = [];
101
+ const dsOptions = await parseProviderOptions({
102
+ provider: "dashscope",
103
+ providerOptions: options.providerOptions,
104
+ schema: imageOptionsSchema
105
+ });
106
+ const body = {
107
+ model: this.modelId,
108
+ input: { messages: [{
109
+ role: "user",
110
+ content: [{ text: options.prompt }]
111
+ }] },
112
+ parameters: {
113
+ ...dsOptions?.size != null && { size: dsOptions.size },
114
+ ...dsOptions?.negativePrompt != null && { negative_prompt: dsOptions.negativePrompt },
115
+ ...dsOptions?.promptExtend != null && { prompt_extend: dsOptions.promptExtend },
116
+ ...dsOptions?.watermark != null && { watermark: dsOptions.watermark },
117
+ ...dsOptions?.n != null && { n: dsOptions.n }
118
+ }
119
+ };
120
+ const { responseHeaders, value: response } = await postJsonToApi({
121
+ url: `${this.config.baseURL}/api/v1/services/aigc/multimodal-generation/generation`,
122
+ headers: combineHeaders(this.config.headers(), options.headers),
123
+ body,
124
+ failedResponseHandler: nativeFailedHandler,
125
+ successfulResponseHandler: createJsonResponseHandler(imageResponseSchema),
126
+ abortSignal: options.abortSignal,
127
+ fetch: this.config.fetch
128
+ });
129
+ const imageUrls = response.output?.choices?.flatMap((c) => c.message.content.filter((p) => p.image != null).map((p) => p.image)) ?? [];
130
+ const images = [];
131
+ for (const url of imageUrls) {
132
+ const buffer = await (await (this.config.fetch ?? fetch)(url, { headers: this.config.headers() })).arrayBuffer();
133
+ images.push(uint8ArrayToBase64(new Uint8Array(buffer)));
134
+ }
135
+ return {
136
+ images,
137
+ warnings,
138
+ response: {
139
+ timestamp: /* @__PURE__ */ new Date(),
140
+ modelId: this.modelId,
141
+ headers: responseHeaders
142
+ }
143
+ };
144
+ }
145
+ };
146
+ //#endregion
147
+ //#region src/rerank.ts
148
+ const rerankResponseSchema = zodSchema(z.object({
149
+ id: z.string().optional(),
150
+ model: z.string().optional(),
151
+ results: z.array(z.object({
152
+ index: z.number(),
153
+ relevance_score: z.number()
154
+ })).optional()
155
+ }));
156
+ var DashScopeRerankingModel = class {
157
+ specificationVersion = "v3";
158
+ modelId;
159
+ config;
160
+ constructor(modelId, config) {
161
+ this.modelId = modelId;
162
+ this.config = config;
163
+ }
164
+ get provider() {
165
+ return this.config.provider;
166
+ }
167
+ async doRerank(options) {
168
+ const warnings = [];
169
+ const documents = options.documents.type === "text" ? options.documents.values : options.documents.values.map((d) => JSON.stringify(d));
170
+ const body = {
171
+ model: this.modelId,
172
+ query: options.query,
173
+ documents,
174
+ ...options.topN != null && { top_n: options.topN }
175
+ };
176
+ const { responseHeaders, value: response } = await postJsonToApi({
177
+ url: `${this.config.baseURL}/compatible-api/v1/reranks`,
178
+ headers: combineHeaders(this.config.headers(), options.headers),
179
+ body,
180
+ failedResponseHandler,
181
+ successfulResponseHandler: createJsonResponseHandler(rerankResponseSchema),
182
+ abortSignal: options.abortSignal,
183
+ fetch: this.config.fetch
184
+ });
185
+ return {
186
+ ranking: (response.results ?? []).map((r) => ({
187
+ index: r.index,
188
+ relevanceScore: r.relevance_score
189
+ })),
190
+ warnings,
191
+ response: {
192
+ id: response.id ?? void 0,
193
+ modelId: response.model ?? void 0,
194
+ headers: responseHeaders
195
+ }
196
+ };
197
+ }
198
+ };
199
+ //#endregion
200
+ //#region src/speech.ts
201
+ const speechOptionsSchema = z.object({
202
+ voice: z.string().optional(),
203
+ format: z.string().optional(),
204
+ sampleRate: z.number().optional(),
205
+ languageType: z.string().optional(),
206
+ speed: z.number().optional(),
207
+ volume: z.number().optional(),
208
+ pitch: z.number().optional()
209
+ });
210
+ const cosyvoiceResponseSchema = zodSchema(z.object({
211
+ output: z.object({ audio: z.object({ url: z.string().optional() }).nullish() }).nullish(),
212
+ request_id: z.string().nullish()
213
+ }));
214
+ var DashScopeSpeechModel = class {
215
+ specificationVersion = "v3";
216
+ modelId;
217
+ config;
218
+ constructor(modelId, config) {
219
+ this.modelId = modelId;
220
+ this.config = config;
221
+ }
222
+ get provider() {
223
+ return this.config.provider;
224
+ }
225
+ async doGenerate(options) {
226
+ const warnings = [];
227
+ const dsOptions = await parseProviderOptions({
228
+ provider: "dashscope",
229
+ providerOptions: options.providerOptions,
230
+ schema: speechOptionsSchema
231
+ });
232
+ const voice = dsOptions?.voice ?? "longanyang";
233
+ const format = dsOptions?.format ?? "wav";
234
+ const sampleRate = dsOptions?.sampleRate ?? 24e3;
235
+ const isCosyVoice = this.modelId.startsWith("cosyvoice");
236
+ let url;
237
+ let body;
238
+ if (isCosyVoice) {
239
+ url = `${this.config.baseURL}/api/v1/services/audio/tts/SpeechSynthesizer`;
240
+ body = {
241
+ model: this.modelId,
242
+ input: {
243
+ text: options.text,
244
+ voice,
245
+ format,
246
+ sample_rate: sampleRate,
247
+ ...dsOptions?.speed != null && { speech_rate: dsOptions.speed },
248
+ ...dsOptions?.volume != null && { volume: dsOptions.volume },
249
+ ...dsOptions?.pitch != null && { pitch_rate: dsOptions.pitch }
250
+ }
251
+ };
252
+ } else {
253
+ url = `${this.config.baseURL}/api/v1/services/aigc/multimodal-generation/generation`;
254
+ body = {
255
+ model: this.modelId,
256
+ input: {
257
+ text: options.text,
258
+ voice,
259
+ ...dsOptions?.languageType != null && { language_type: dsOptions.languageType }
260
+ }
261
+ };
262
+ }
263
+ const { responseHeaders, value: response } = await postJsonToApi({
264
+ url,
265
+ headers: combineHeaders(this.config.headers(), options.headers),
266
+ body,
267
+ failedResponseHandler: nativeFailedHandler,
268
+ successfulResponseHandler: createJsonResponseHandler(cosyvoiceResponseSchema),
269
+ abortSignal: options.abortSignal,
270
+ fetch: this.config.fetch
271
+ });
272
+ const audioUrl = response.output?.audio?.url;
273
+ if (!audioUrl) throw new Error("No audio URL returned from TTS API");
274
+ const audioBuffer = await (await (this.config.fetch ?? fetch)(audioUrl, { headers: this.config.headers() })).arrayBuffer();
275
+ return {
276
+ audio: new Uint8Array(audioBuffer),
277
+ warnings,
278
+ request: { body },
279
+ response: {
280
+ timestamp: /* @__PURE__ */ new Date(),
281
+ modelId: this.modelId,
282
+ headers: responseHeaders
283
+ }
284
+ };
21
285
  }
22
286
  };
23
287
  //#endregion
@@ -95,6 +359,342 @@ const responsesTools = {
95
359
  mcp: (args) => mcpToolFactory(args)
96
360
  };
97
361
  //#endregion
362
+ //#region src/transcription.ts
363
+ const transcriptionOptionsSchema = z.object({
364
+ fileUrl: z.string().optional(),
365
+ languageHints: z.array(z.string()).optional(),
366
+ enableItn: z.boolean().optional(),
367
+ enableWords: z.boolean().optional(),
368
+ channelId: z.array(z.number()).optional(),
369
+ pollIntervalMs: z.number().positive().optional(),
370
+ pollTimeoutMs: z.number().positive().optional()
371
+ });
372
+ const syncResponseSchema = zodSchema(z.object({
373
+ output: z.object({ choices: z.array(z.object({ message: z.object({ content: z.array(z.object({ text: z.string().optional() })) }) })).optional() }).nullish(),
374
+ request_id: z.string().nullish()
375
+ }));
376
+ const createTaskSchema$1 = zodSchema(z.object({
377
+ output: z.object({
378
+ task_id: z.string(),
379
+ task_status: z.string()
380
+ }).nullish(),
381
+ request_id: z.string().nullish()
382
+ }));
383
+ const taskStatusSchema$1 = zodSchema(z.object({
384
+ output: z.object({
385
+ task_id: z.string(),
386
+ task_status: z.string(),
387
+ result: z.object({ transcription_url: z.string().nullish() }).nullish(),
388
+ results: z.array(z.object({
389
+ subtask_status: z.string().nullish(),
390
+ transcription_url: z.string().nullish()
391
+ })).nullish(),
392
+ code: z.string().nullish(),
393
+ message: z.string().nullish()
394
+ }).nullish(),
395
+ request_id: z.string().nullish()
396
+ }));
397
+ function isAsyncModel(modelId) {
398
+ return modelId.includes("filetrans") || modelId.startsWith("fun-asr") || modelId.startsWith("paraformer");
399
+ }
400
+ function buildAudioUrl(audio, mediaType) {
401
+ if (typeof audio === "string") {
402
+ if (audio.startsWith("http")) return audio;
403
+ return `data:${mediaType};base64,${audio}`;
404
+ }
405
+ return `data:${mediaType};base64,${uint8ArrayToBase64(audio)}`;
406
+ }
407
+ var DashScopeTranscriptionModel = class {
408
+ specificationVersion = "v3";
409
+ modelId;
410
+ config;
411
+ constructor(modelId, config) {
412
+ this.modelId = modelId;
413
+ this.config = config;
414
+ }
415
+ get provider() {
416
+ return this.config.provider;
417
+ }
418
+ async doGenerate(options) {
419
+ const warnings = [];
420
+ const dsOptions = await parseProviderOptions({
421
+ provider: "dashscope",
422
+ providerOptions: options.providerOptions,
423
+ schema: transcriptionOptionsSchema
424
+ }) ?? null;
425
+ if (isAsyncModel(this.modelId) && dsOptions?.fileUrl) return this.doAsync(options, dsOptions, warnings);
426
+ return this.doSync(options, dsOptions, warnings);
427
+ }
428
+ async doSync(options, dsOptions, warnings) {
429
+ const audioUrl = buildAudioUrl(options.audio, options.mediaType);
430
+ const body = {
431
+ model: this.modelId,
432
+ input: { messages: [{
433
+ role: "user",
434
+ content: [{ audio: audioUrl }]
435
+ }] },
436
+ parameters: {
437
+ result_format: "message",
438
+ ...dsOptions?.enableItn != null && { asr_options: { enable_itn: dsOptions.enableItn } }
439
+ }
440
+ };
441
+ const { responseHeaders, value: response } = await postJsonToApi({
442
+ url: `${this.config.baseURL}/api/v1/services/aigc/multimodal-generation/generation`,
443
+ headers: combineHeaders(this.config.headers(), options.headers),
444
+ body,
445
+ failedResponseHandler: nativeFailedHandler,
446
+ successfulResponseHandler: createJsonResponseHandler(syncResponseSchema),
447
+ abortSignal: options.abortSignal,
448
+ fetch: this.config.fetch
449
+ });
450
+ return {
451
+ text: response.output?.choices?.[0]?.message.content.filter((p) => p.text != null).map((p) => p.text).join("") ?? "",
452
+ segments: [],
453
+ language: void 0,
454
+ durationInSeconds: void 0,
455
+ warnings,
456
+ request: { body },
457
+ response: {
458
+ timestamp: /* @__PURE__ */ new Date(),
459
+ modelId: this.modelId,
460
+ headers: responseHeaders
461
+ }
462
+ };
463
+ }
464
+ async doAsync(options, dsOptions, warnings) {
465
+ const audioUrl = dsOptions?.fileUrl;
466
+ if (!audioUrl) throw new AISDKError({
467
+ name: "DASHSCOPE_TRANSCRIPTION_ERROR",
468
+ message: "Async transcription requires providerOptions.dashscope.fileUrl with a publicly accessible audio URL."
469
+ });
470
+ const parameters = {};
471
+ if (dsOptions?.channelId != null) parameters.channel_id = dsOptions.channelId;
472
+ if (dsOptions?.enableItn != null) parameters.enable_itn = dsOptions.enableItn;
473
+ if (dsOptions?.enableWords != null) parameters.enable_words = dsOptions.enableWords;
474
+ if (dsOptions?.languageHints?.length) parameters.language_hints = dsOptions.languageHints;
475
+ const { value: createResponse } = await postJsonToApi({
476
+ url: `${this.config.baseURL}/api/v1/services/audio/asr/transcription`,
477
+ headers: combineHeaders(this.config.headers(), options.headers, { "X-DashScope-Async": "enable" }),
478
+ body: {
479
+ model: this.modelId,
480
+ input: { file_url: audioUrl },
481
+ ...Object.keys(parameters).length > 0 && { parameters }
482
+ },
483
+ successfulResponseHandler: createJsonResponseHandler(createTaskSchema$1),
484
+ failedResponseHandler: nativeFailedHandler,
485
+ abortSignal: options.abortSignal,
486
+ fetch: this.config.fetch
487
+ });
488
+ const taskId = createResponse.output?.task_id;
489
+ if (!taskId) throw new AISDKError({
490
+ name: "DASHSCOPE_TRANSCRIPTION_ERROR",
491
+ message: `No task_id returned. Response: ${JSON.stringify(createResponse)}`
492
+ });
493
+ const pollInterval = dsOptions?.pollIntervalMs ?? 5e3;
494
+ const pollTimeout = dsOptions?.pollTimeoutMs ?? 6e5;
495
+ const startTime = Date.now();
496
+ while (true) {
497
+ await delay(pollInterval, { abortSignal: options.abortSignal });
498
+ if (Date.now() - startTime > pollTimeout) throw new AISDKError({
499
+ name: "DASHSCOPE_TRANSCRIPTION_TIMEOUT",
500
+ message: `Transcription timed out after ${pollTimeout}ms`
501
+ });
502
+ const { value: status, responseHeaders } = await getFromApi({
503
+ url: `${this.config.baseURL}/api/v1/tasks/${taskId}`,
504
+ headers: combineHeaders(this.config.headers(), options.headers, { "X-DashScope-Async": "enable" }),
505
+ successfulResponseHandler: createJsonResponseHandler(taskStatusSchema$1),
506
+ failedResponseHandler: nativeFailedHandler,
507
+ abortSignal: options.abortSignal,
508
+ fetch: this.config.fetch
509
+ });
510
+ const taskStatus = status.output?.task_status;
511
+ if (taskStatus === "SUCCEEDED") {
512
+ let transcriptionUrl = status.output?.result?.transcription_url;
513
+ if (!transcriptionUrl) transcriptionUrl = ((status.output?.results)?.find((r) => r.subtask_status === "SUCCEEDED"))?.transcription_url;
514
+ if (!transcriptionUrl) throw new AISDKError({
515
+ name: "DASHSCOPE_TRANSCRIPTION_ERROR",
516
+ message: `No transcription URL in response. Task ID: ${taskId}`
517
+ });
518
+ const resultData = await (await (this.config.fetch ?? fetch)(transcriptionUrl)).json();
519
+ let text = "";
520
+ const segments = [];
521
+ if (resultData.transcripts) for (const transcript of resultData.transcripts) {
522
+ text += transcript.text;
523
+ if (transcript.sentences) {
524
+ for (const sentence of transcript.sentences) if (sentence.begin_time != null && sentence.end_time != null) segments.push({
525
+ text: sentence.text,
526
+ startSecond: sentence.begin_time / 1e3,
527
+ endSecond: sentence.end_time / 1e3
528
+ });
529
+ }
530
+ }
531
+ return {
532
+ text,
533
+ segments,
534
+ language: void 0,
535
+ durationInSeconds: void 0,
536
+ warnings,
537
+ response: {
538
+ timestamp: /* @__PURE__ */ new Date(),
539
+ modelId: this.modelId,
540
+ headers: responseHeaders
541
+ }
542
+ };
543
+ }
544
+ if (taskStatus === "FAILED" || taskStatus === "CANCELED") throw new AISDKError({
545
+ name: "DASHSCOPE_TRANSCRIPTION_FAILED",
546
+ message: `Transcription ${taskStatus.toLowerCase()}. ${status.output?.message ?? ""}`
547
+ });
548
+ }
549
+ }
550
+ };
551
+ //#endregion
552
+ //#region src/types.ts
553
+ const DASHSCOPE_REGION_URLS = {
554
+ beijing: "https://dashscope.aliyuncs.com",
555
+ singapore: "https://dashscope-intl.aliyuncs.com",
556
+ us: "https://dashscope-us.aliyuncs.com",
557
+ germany: "https://{workspaceId}.eu-central-1.maas.aliyuncs.com"
558
+ };
559
+ //#endregion
560
+ //#region src/video.ts
561
+ const videoOptionsSchema = z.object({
562
+ negativePrompt: z.string().optional(),
563
+ promptExtend: z.boolean().optional(),
564
+ watermark: z.boolean().optional(),
565
+ resolution: z.string().optional(),
566
+ size: z.string().optional(),
567
+ duration: z.number().optional(),
568
+ pollIntervalMs: z.number().positive().optional(),
569
+ pollTimeoutMs: z.number().positive().optional()
570
+ });
571
+ const createTaskSchema = zodSchema(z.object({
572
+ output: z.object({
573
+ task_id: z.string(),
574
+ task_status: z.string()
575
+ }).nullish(),
576
+ request_id: z.string().nullish()
577
+ }));
578
+ const taskStatusSchema = zodSchema(z.object({
579
+ output: z.object({
580
+ task_id: z.string(),
581
+ task_status: z.string(),
582
+ video_url: z.string().nullish(),
583
+ submit_time: z.string().nullish(),
584
+ scheduled_time: z.string().nullish(),
585
+ end_time: z.string().nullish(),
586
+ code: z.string().nullish(),
587
+ message: z.string().nullish()
588
+ }).nullish(),
589
+ usage: z.object({
590
+ duration: z.number().nullish(),
591
+ output_video_duration: z.number().nullish(),
592
+ size: z.string().nullish()
593
+ }).nullish(),
594
+ request_id: z.string().nullish()
595
+ }));
596
+ function detectMode(modelId) {
597
+ return modelId.includes("-i2v") ? "i2v" : "t2v";
598
+ }
599
+ var DashScopeVideoModel = class {
600
+ specificationVersion = "v3";
601
+ modelId;
602
+ config;
603
+ constructor(modelId, config) {
604
+ this.modelId = modelId;
605
+ this.config = config;
606
+ }
607
+ get provider() {
608
+ return this.config.provider;
609
+ }
610
+ get maxVideosPerCall() {
611
+ return 1;
612
+ }
613
+ async doGenerate(options) {
614
+ const warnings = [];
615
+ const mode = detectMode(this.modelId);
616
+ const dsOptions = await parseProviderOptions({
617
+ provider: "dashscope",
618
+ providerOptions: options.providerOptions,
619
+ schema: videoOptionsSchema
620
+ });
621
+ const input = {};
622
+ if (options.prompt != null) input.prompt = options.prompt;
623
+ if (dsOptions?.negativePrompt != null) input.negative_prompt = dsOptions.negativePrompt;
624
+ if (mode === "i2v" && options.image != null) if (options.image.type === "url") input.img_url = options.image.url;
625
+ else input.img_url = typeof options.image.data === "string" ? options.image.data : uint8ArrayToBase64(options.image.data);
626
+ const parameters = {};
627
+ if (dsOptions?.duration != null) parameters.duration = dsOptions.duration;
628
+ if (options.seed != null) parameters.seed = options.seed;
629
+ if (dsOptions?.promptExtend != null) parameters.prompt_extend = dsOptions.promptExtend;
630
+ if (dsOptions?.watermark != null) parameters.watermark = dsOptions.watermark;
631
+ if (mode === "i2v" && dsOptions?.resolution != null) parameters.resolution = dsOptions.resolution;
632
+ else if (options.resolution != null) parameters.size = options.resolution.replace("x", "*");
633
+ else if (dsOptions?.size != null) parameters.size = dsOptions.size;
634
+ const { value: createResponse } = await postJsonToApi({
635
+ url: `${this.config.baseURL}/api/v1/services/aigc/video-generation/video-synthesis`,
636
+ headers: combineHeaders(this.config.headers(), options.headers, { "X-DashScope-Async": "enable" }),
637
+ body: {
638
+ model: this.modelId,
639
+ input,
640
+ parameters
641
+ },
642
+ successfulResponseHandler: createJsonResponseHandler(createTaskSchema),
643
+ failedResponseHandler: nativeFailedHandler,
644
+ abortSignal: options.abortSignal,
645
+ fetch: this.config.fetch
646
+ });
647
+ const taskId = createResponse.output?.task_id;
648
+ if (!taskId) throw new AISDKError({
649
+ name: "DASHSCOPE_VIDEO_ERROR",
650
+ message: `No task_id returned. Response: ${JSON.stringify(createResponse)}`
651
+ });
652
+ const pollInterval = dsOptions?.pollIntervalMs ?? 5e3;
653
+ const pollTimeout = dsOptions?.pollTimeoutMs ?? 6e5;
654
+ const startTime = Date.now();
655
+ while (true) {
656
+ await delay(pollInterval, { abortSignal: options.abortSignal });
657
+ if (Date.now() - startTime > pollTimeout) throw new AISDKError({
658
+ name: "DASHSCOPE_VIDEO_TIMEOUT",
659
+ message: `Video generation timed out after ${pollTimeout}ms`
660
+ });
661
+ const { value: status, responseHeaders } = await getFromApi({
662
+ url: `${this.config.baseURL}/api/v1/tasks/${taskId}`,
663
+ headers: combineHeaders(this.config.headers(), options.headers),
664
+ successfulResponseHandler: createJsonResponseHandler(taskStatusSchema),
665
+ failedResponseHandler: nativeFailedHandler,
666
+ abortSignal: options.abortSignal,
667
+ fetch: this.config.fetch
668
+ });
669
+ const taskStatus = status.output?.task_status;
670
+ if (taskStatus === "SUCCEEDED") {
671
+ const videoUrl = status.output?.video_url;
672
+ if (!videoUrl) throw new AISDKError({
673
+ name: "DASHSCOPE_VIDEO_ERROR",
674
+ message: `No video URL in response. Task ID: ${taskId}`
675
+ });
676
+ return {
677
+ videos: [{
678
+ type: "url",
679
+ url: videoUrl,
680
+ mediaType: "video/mp4"
681
+ }],
682
+ warnings,
683
+ response: {
684
+ timestamp: /* @__PURE__ */ new Date(),
685
+ modelId: this.modelId,
686
+ headers: responseHeaders
687
+ }
688
+ };
689
+ }
690
+ if (taskStatus === "FAILED" || taskStatus === "CANCELED") throw new AISDKError({
691
+ name: "DASHSCOPE_VIDEO_FAILED",
692
+ message: `Video generation ${taskStatus.toLowerCase()}. ${status.output?.message ?? ""}`
693
+ });
694
+ }
695
+ }
696
+ };
697
+ //#endregion
98
698
  //#region src/chat.ts
99
699
  const chatOptionsSchema = z.object({
100
700
  enableThinking: z.boolean().optional(),
@@ -165,45 +765,6 @@ const chatChunkSchema = z.object({
165
765
  })),
166
766
  usage: usageSchema.nullish()
167
767
  });
168
- const failedResponseHandler$1 = createJsonErrorResponseHandler({
169
- errorSchema: z.object({ error: z.object({
170
- message: z.string(),
171
- code: z.string().nullish(),
172
- type: z.string().nullish()
173
- }) }),
174
- errorToMessage: (data) => data.error.message
175
- });
176
- function convertUsage$1(usage) {
177
- if (!usage) return {
178
- inputTokens: {
179
- total: 0,
180
- noCache: void 0,
181
- cacheRead: void 0,
182
- cacheWrite: void 0
183
- },
184
- outputTokens: {
185
- total: 0,
186
- text: void 0,
187
- reasoning: void 0
188
- }
189
- };
190
- const cacheRead = usage.prompt_tokens_details?.cached_tokens ?? void 0;
191
- const cacheWrite = usage.prompt_tokens_details?.cache_creation_input_tokens ?? void 0;
192
- const noCache = cacheRead != null || cacheWrite != null ? (usage.prompt_tokens ?? 0) - (cacheRead ?? 0) - (cacheWrite ?? 0) : void 0;
193
- return {
194
- inputTokens: {
195
- total: usage.prompt_tokens ?? 0,
196
- noCache,
197
- cacheRead,
198
- cacheWrite
199
- },
200
- outputTokens: {
201
- total: usage.completion_tokens ?? 0,
202
- text: void 0,
203
- reasoning: usage.completion_tokens_details?.reasoning_tokens ?? void 0
204
- }
205
- };
206
- }
207
768
  function convertMessages(prompt) {
208
769
  const messages = [];
209
770
  for (const { role, content } of prompt) switch (role) {
@@ -333,14 +894,7 @@ var DashScopeChatLanguageModel = class {
333
894
  ...options.presencePenalty != null && { presence_penalty: options.presencePenalty },
334
895
  ...options.stopSequences?.length && { stop: options.stopSequences },
335
896
  ...options.seed != null && { seed: options.seed },
336
- ...options.responseFormat?.type === "json" && { response_format: options.responseFormat.schema != null ? {
337
- type: "json_schema",
338
- json_schema: {
339
- schema: options.responseFormat.schema,
340
- name: options.responseFormat.name ?? "response",
341
- description: options.responseFormat.description
342
- }
343
- } : { type: "json_object" } },
897
+ ...options.responseFormat?.type === "json" && { response_format: { type: "json_object" } },
344
898
  ...apiTools != null && {
345
899
  tools: apiTools,
346
900
  tool_choice: toolChoice
@@ -358,10 +912,10 @@ var DashScopeChatLanguageModel = class {
358
912
  async doGenerate(options) {
359
913
  const { args, warnings } = await this.getArgs(options);
360
914
  const { responseHeaders, value: response } = await postJsonToApi({
361
- url: `${this.config.baseURL}/chat/completions`,
915
+ url: `${this.config.baseURL}/compatible-mode/v1/chat/completions`,
362
916
  headers: combineHeaders(this.config.headers(), options.headers),
363
917
  body: args,
364
- failedResponseHandler: failedResponseHandler$1,
918
+ failedResponseHandler,
365
919
  successfulResponseHandler: createJsonResponseHandler(chatResponseSchema),
366
920
  abortSignal: options.abortSignal,
367
921
  fetch: this.config.fetch
@@ -388,12 +942,10 @@ var DashScopeChatLanguageModel = class {
388
942
  unified: mapOpenAICompatibleFinishReason(choice.finish_reason),
389
943
  raw: choice.finish_reason ?? void 0
390
944
  },
391
- usage: convertUsage$1(response.usage),
945
+ usage: convertOpenAICompatibleChatUsage(response.usage),
392
946
  request: { body: JSON.stringify(args) },
393
947
  response: {
394
- id: response.id ?? void 0,
395
- modelId: response.model ?? void 0,
396
- timestamp: response.created ? /* @__PURE__ */ new Date(response.created * 1e3) : void 0,
948
+ ...getResponseMetadata(response),
397
949
  headers: responseHeaders
398
950
  },
399
951
  warnings
@@ -406,10 +958,10 @@ var DashScopeChatLanguageModel = class {
406
958
  stream: true
407
959
  };
408
960
  const { responseHeaders, value: response } = await postJsonToApi({
409
- url: `${this.config.baseURL}/chat/completions`,
961
+ url: `${this.config.baseURL}/compatible-mode/v1/chat/completions`,
410
962
  headers: combineHeaders(this.config.headers(), options.headers),
411
963
  body,
412
- failedResponseHandler: failedResponseHandler$1,
964
+ failedResponseHandler,
413
965
  successfulResponseHandler: createEventSourceResponseHandler(chatChunkSchema),
414
966
  abortSignal: options.abortSignal,
415
967
  fetch: this.config.fetch
@@ -448,9 +1000,7 @@ var DashScopeChatLanguageModel = class {
448
1000
  isFirstChunk = false;
449
1001
  controller.enqueue({
450
1002
  type: "response-metadata",
451
- id: value.id ?? void 0,
452
- modelId: value.model ?? void 0,
453
- timestamp: value.created ? /* @__PURE__ */ new Date(value.created * 1e3) : void 0
1003
+ ...getResponseMetadata(value)
454
1004
  });
455
1005
  }
456
1006
  if (value.usage != null) usage = value.usage;
@@ -594,7 +1144,7 @@ var DashScopeChatLanguageModel = class {
594
1144
  controller.enqueue({
595
1145
  type: "finish",
596
1146
  finishReason,
597
- usage: convertUsage$1(usage)
1147
+ usage: convertOpenAICompatibleChatUsage(usage)
598
1148
  });
599
1149
  }
600
1150
  })),
@@ -619,11 +1169,6 @@ const responsesOptionsSchema = zodSchema(z.object({
619
1169
  instructions: z.string().optional(),
620
1170
  includeUsage: z.boolean().optional()
621
1171
  }));
622
- const errorSchema = zodSchema(z.object({ error: z.object({
623
- message: z.string(),
624
- type: z.string().optional(),
625
- code: z.string().optional()
626
- }) }));
627
1172
  const responseSchema = zodSchema(z.object({
628
1173
  id: z.string(),
629
1174
  created_at: z.number().optional(),
@@ -641,41 +1186,6 @@ const responseSchema = zodSchema(z.object({
641
1186
  error: z.object({ message: z.string() }).nullable().optional()
642
1187
  }).loose());
643
1188
  const streamChunkSchema = zodSchema(z.object({ type: z.string() }).loose());
644
- const failedResponseHandler = createJsonErrorResponseHandler({
645
- errorSchema,
646
- errorToMessage: (data) => data.error.message
647
- });
648
- function convertUsage(usage) {
649
- if (!usage) return {
650
- inputTokens: {
651
- total: 0,
652
- noCache: void 0,
653
- cacheRead: void 0,
654
- cacheWrite: void 0
655
- },
656
- outputTokens: {
657
- total: 0,
658
- text: void 0,
659
- reasoning: void 0
660
- }
661
- };
662
- const details = usage.output_tokens_details;
663
- const inputDetails = usage.input_tokens_details;
664
- return {
665
- inputTokens: {
666
- total: usage.input_tokens ?? 0,
667
- noCache: void 0,
668
- cacheRead: inputDetails?.cached_tokens ?? void 0,
669
- cacheWrite: void 0
670
- },
671
- outputTokens: {
672
- total: usage.output_tokens ?? 0,
673
- text: void 0,
674
- reasoning: details?.reasoning_tokens ?? void 0
675
- },
676
- raw: usage
677
- };
678
- }
679
1189
  function mapFinishReason(status) {
680
1190
  switch (status) {
681
1191
  case "completed": return {
@@ -1047,7 +1557,7 @@ var DashScopeResponsesLanguageModel = class {
1047
1557
  async doGenerate(options) {
1048
1558
  const { args: body, warnings } = await this.getArgs(options);
1049
1559
  const { responseHeaders, value: response } = await postJsonToApi({
1050
- url: `${this.config.baseURL}/responses`,
1560
+ url: `${this.config.baseURL}/compatible-mode/v1/responses`,
1051
1561
  headers: combineHeaders(this.config.headers(), options.headers),
1052
1562
  body,
1053
1563
  failedResponseHandler,
@@ -1066,7 +1576,7 @@ var DashScopeResponsesLanguageModel = class {
1066
1576
  return {
1067
1577
  content,
1068
1578
  finishReason,
1069
- usage: convertUsage(response.usage),
1579
+ usage: convertResponsesUsage(response.usage),
1070
1580
  request: { body },
1071
1581
  response: {
1072
1582
  id: response.id ?? void 0,
@@ -1083,7 +1593,7 @@ var DashScopeResponsesLanguageModel = class {
1083
1593
  async doStream(options) {
1084
1594
  const { args: body, warnings } = await this.getArgs(options);
1085
1595
  const { responseHeaders, value: response } = await postJsonToApi({
1086
- url: `${this.config.baseURL}/responses`,
1596
+ url: `${this.config.baseURL}/compatible-mode/v1/responses`,
1087
1597
  headers: combineHeaders(this.config.headers(), options.headers),
1088
1598
  body: {
1089
1599
  ...body,
@@ -1151,7 +1661,7 @@ var DashScopeResponsesLanguageModel = class {
1151
1661
  case "response.completed": {
1152
1662
  const resp = val.response;
1153
1663
  finishReason = mapFinishReason(resp?.status);
1154
- if (resp?.usage) usage = convertUsage(resp.usage);
1664
+ if (resp?.usage) usage = convertResponsesUsage(resp.usage);
1155
1665
  if (resp?.id) controller.enqueue({
1156
1666
  type: "response-metadata",
1157
1667
  id: resp.id,
@@ -1192,10 +1702,9 @@ var DashScopeResponsesLanguageModel = class {
1192
1702
  //#endregion
1193
1703
  //#region src/provider.ts
1194
1704
  function createDashScope(options = {}) {
1195
- const { region = "beijing", workspaceId, baseURL: explicitBaseURL, videoBaseURL: _explicitVideoBaseURL, includeUsage, ...rest } = options;
1196
- const regionUrls = DASHSCOPE_REGION_BASE_URLS[region];
1197
- const baseURL = (explicitBaseURL ?? regionUrls.baseURL).replace("{workspaceId}", workspaceId ?? "");
1705
+ const { region = "beijing", workspaceId, baseURL: explicitBaseURL, includeUsage, ...rest } = options;
1198
1706
  if (region === "germany" && !explicitBaseURL && !workspaceId) throw new Error("workspaceId is required when region is 'germany'. See https://help.aliyun.com/zh/model-studio/obtain-the-app-id-and-workspace-id");
1707
+ const baseURL = (explicitBaseURL ?? DASHSCOPE_REGION_URLS[region]).replace("{workspaceId}", workspaceId ?? "");
1199
1708
  const apiKey = rest.apiKey ?? process.env.DASHSCOPE_API_KEY;
1200
1709
  const getHeaders = () => {
1201
1710
  const headers = {};
@@ -1203,23 +1712,53 @@ function createDashScope(options = {}) {
1203
1712
  if (rest.headers) Object.assign(headers, rest.headers);
1204
1713
  return headers;
1205
1714
  };
1206
- const chatConfig = {
1715
+ const baseConfig = {
1207
1716
  provider: "dashscope",
1208
1717
  baseURL,
1209
1718
  headers: getHeaders,
1210
- fetch: rest.fetch,
1211
- includeUsage
1719
+ fetch: rest.fetch
1212
1720
  };
1213
- const createChatModel = (modelId) => new DashScopeChatLanguageModel(modelId, chatConfig);
1721
+ const createChatModel = (modelId) => new DashScopeChatLanguageModel(modelId, {
1722
+ ...baseConfig,
1723
+ includeUsage
1724
+ });
1725
+ const createEmbeddingModel = (modelId) => new DashScopeEmbeddingModel(modelId, {
1726
+ ...baseConfig,
1727
+ includeUsage
1728
+ });
1729
+ const createRerankingModel = (modelId) => new DashScopeRerankingModel(modelId, {
1730
+ ...baseConfig,
1731
+ provider: "dashscope.rerank"
1732
+ });
1214
1733
  const createResponsesModel = (modelId) => new DashScopeResponsesLanguageModel(modelId, {
1215
- provider: "dashscope.responses",
1216
- baseURL,
1217
- headers: getHeaders,
1218
- fetch: rest.fetch
1734
+ ...baseConfig,
1735
+ provider: "dashscope.responses"
1219
1736
  });
1220
1737
  const responses = Object.assign(createResponsesModel, { tools: responsesTools });
1738
+ const createImageModel = (modelId) => new DashScopeImageModel(modelId, {
1739
+ ...baseConfig,
1740
+ provider: "dashscope.image"
1741
+ });
1742
+ const createVideoModel = (modelId) => new DashScopeVideoModel(modelId, {
1743
+ ...baseConfig,
1744
+ provider: "dashscope.video"
1745
+ });
1746
+ const createSpeechModel = (modelId) => new DashScopeSpeechModel(modelId, {
1747
+ ...baseConfig,
1748
+ provider: "dashscope.speech"
1749
+ });
1750
+ const createTranscriptionModel = (modelId) => new DashScopeTranscriptionModel(modelId, {
1751
+ ...baseConfig,
1752
+ provider: "dashscope.transcription"
1753
+ });
1221
1754
  return Object.assign(createChatModel, {
1222
1755
  languageModel: createChatModel,
1756
+ embeddingModel: createEmbeddingModel,
1757
+ rerankingModel: createRerankingModel,
1758
+ imageModel: createImageModel,
1759
+ videoModel: createVideoModel,
1760
+ speechModel: createSpeechModel,
1761
+ transcriptionModel: createTranscriptionModel,
1223
1762
  chatOptions: (chatOpts) => ({ providerOptions: { dashscope: chatOpts } }),
1224
1763
  responsesOptions: (responsesOpts) => ({ providerOptions: { dashscope: responsesOpts } }),
1225
1764
  responses
@@ -1229,4 +1768,4 @@ function createDashScope(options = {}) {
1229
1768
  //#region src/index.ts
1230
1769
  const dashscope = createDashScope();
1231
1770
  //#endregion
1232
- export { DASHSCOPE_REGION_BASE_URLS, createDashScope, dashscope, responsesTools };
1771
+ export { DASHSCOPE_REGION_URLS, DashScopeEmbeddingModel, DashScopeImageModel, DashScopeRerankingModel, DashScopeSpeechModel, DashScopeTranscriptionModel, DashScopeVideoModel, createDashScope, dashscope, responsesTools };