@agentor/dashscope 0.0.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/dist/index.mjs ADDED
@@ -0,0 +1,1232 @@
1
+ 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"
21
+ }
22
+ };
23
+ //#endregion
24
+ //#region src/tools.ts
25
+ const webSearchToolFactory = createProviderToolFactoryWithOutputSchema({
26
+ id: "dashscope.web_search",
27
+ inputSchema: lazySchema(() => zodSchema(z.object({}))),
28
+ outputSchema: lazySchema(() => zodSchema(z.object({
29
+ query: z.string().optional(),
30
+ sources: z.array(z.object({
31
+ type: z.literal("url"),
32
+ url: z.string()
33
+ })).optional()
34
+ })))
35
+ });
36
+ const codeInterpreterToolFactory = createProviderToolFactoryWithOutputSchema({
37
+ id: "dashscope.code_interpreter",
38
+ inputSchema: lazySchema(() => zodSchema(z.object({}))),
39
+ outputSchema: lazySchema(() => zodSchema(z.object({
40
+ code: z.string().optional(),
41
+ outputs: z.array(z.object({
42
+ type: z.literal("logs"),
43
+ logs: z.string().optional()
44
+ })).optional()
45
+ })))
46
+ });
47
+ const webExtractorToolFactory = createProviderToolFactoryWithOutputSchema({
48
+ id: "dashscope.web_extractor",
49
+ inputSchema: lazySchema(() => zodSchema(z.object({}))),
50
+ outputSchema: lazySchema(() => zodSchema(z.object({
51
+ urls: z.array(z.string()).optional(),
52
+ goal: z.string().optional(),
53
+ output: z.string().optional()
54
+ })))
55
+ });
56
+ const fileSearchToolFactory = createProviderToolFactoryWithOutputSchema({
57
+ id: "dashscope.file_search",
58
+ inputSchema: lazySchema(() => zodSchema(z.object({}))),
59
+ outputSchema: lazySchema(() => zodSchema(z.object({
60
+ queries: z.array(z.string()).optional(),
61
+ results: z.array(z.object({
62
+ fileId: z.string().optional(),
63
+ filename: z.string().optional(),
64
+ score: z.number().optional(),
65
+ text: z.string().optional()
66
+ })).optional()
67
+ })))
68
+ });
69
+ const webSearchImageToolFactory = createProviderToolFactoryWithOutputSchema({
70
+ id: "dashscope.web_search_image",
71
+ inputSchema: lazySchema(() => zodSchema(z.object({}))),
72
+ outputSchema: lazySchema(() => zodSchema(z.object({ queries: z.array(z.string()).optional() })))
73
+ });
74
+ const imageSearchToolFactory = createProviderToolFactoryWithOutputSchema({
75
+ id: "dashscope.image_search",
76
+ inputSchema: lazySchema(() => zodSchema(z.object({}))),
77
+ outputSchema: lazySchema(() => zodSchema(z.object({})))
78
+ });
79
+ const mcpToolFactory = createProviderToolFactoryWithOutputSchema({
80
+ id: "dashscope.mcp",
81
+ inputSchema: lazySchema(() => zodSchema(z.object({}))),
82
+ outputSchema: lazySchema(() => zodSchema(z.object({})))
83
+ });
84
+ /**
85
+ * Built-in tools for the Responses API.
86
+ * Access via `dashscope.responses.tools`.
87
+ */
88
+ const responsesTools = {
89
+ webSearch: (args = {}) => webSearchToolFactory(args),
90
+ codeInterpreter: (args = {}) => codeInterpreterToolFactory(args),
91
+ webExtractor: (args = {}) => webExtractorToolFactory(args),
92
+ fileSearch: (args) => fileSearchToolFactory(args),
93
+ webSearchImage: (args = {}) => webSearchImageToolFactory(args),
94
+ imageSearch: (args = {}) => imageSearchToolFactory(args),
95
+ mcp: (args) => mcpToolFactory(args)
96
+ };
97
+ //#endregion
98
+ //#region src/chat.ts
99
+ const chatOptionsSchema = z.object({
100
+ enableThinking: z.boolean().optional(),
101
+ thinkingBudget: z.number().positive().optional(),
102
+ parallelToolCalls: z.boolean().optional(),
103
+ enableSearch: z.boolean().optional(),
104
+ searchStrategy: z.enum([
105
+ "enable",
106
+ "enable_with_history",
107
+ "agent_max"
108
+ ]).optional(),
109
+ enableCodeInterpreter: z.boolean().optional()
110
+ });
111
+ const usageSchema = z.object({
112
+ prompt_tokens: z.number(),
113
+ completion_tokens: z.number(),
114
+ total_tokens: z.number(),
115
+ prompt_tokens_details: z.object({
116
+ cached_tokens: z.number().nullish(),
117
+ cache_creation_input_tokens: z.number().nullish()
118
+ }).nullish(),
119
+ completion_tokens_details: z.object({ reasoning_tokens: z.number().nullish() }).nullish()
120
+ });
121
+ const chatResponseSchema = z.object({
122
+ id: z.string().nullish(),
123
+ created: z.number().nullish(),
124
+ model: z.string().nullish(),
125
+ choices: z.array(z.object({
126
+ message: z.object({
127
+ role: z.literal("assistant").nullish(),
128
+ content: z.string().nullish(),
129
+ reasoning_content: z.string().nullish(),
130
+ tool_calls: z.array(z.object({
131
+ id: z.string(),
132
+ type: z.literal("function"),
133
+ function: z.object({
134
+ name: z.string(),
135
+ arguments: z.string()
136
+ })
137
+ })).nullish()
138
+ }),
139
+ finish_reason: z.string().nullish(),
140
+ index: z.number()
141
+ })),
142
+ usage: usageSchema.nullish()
143
+ });
144
+ const chatChunkSchema = z.object({
145
+ id: z.string().nullish(),
146
+ created: z.number().nullish(),
147
+ model: z.string().nullish(),
148
+ choices: z.array(z.object({
149
+ delta: z.object({
150
+ role: z.enum(["assistant"]).nullish(),
151
+ content: z.string().nullish(),
152
+ reasoning_content: z.string().nullish(),
153
+ tool_calls: z.array(z.object({
154
+ index: z.number().nullish(),
155
+ id: z.string().nullish(),
156
+ type: z.literal("function").nullish(),
157
+ function: z.object({
158
+ name: z.string().nullish(),
159
+ arguments: z.string().nullish()
160
+ }).nullish()
161
+ })).nullish()
162
+ }),
163
+ finish_reason: z.string().nullish(),
164
+ index: z.number()
165
+ })),
166
+ usage: usageSchema.nullish()
167
+ });
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
+ function convertMessages(prompt) {
208
+ const messages = [];
209
+ for (const { role, content } of prompt) switch (role) {
210
+ case "system":
211
+ messages.push({
212
+ role: "system",
213
+ content
214
+ });
215
+ break;
216
+ case "user": {
217
+ const parts = [];
218
+ for (const part of content) switch (part.type) {
219
+ case "text":
220
+ parts.push({
221
+ type: "text",
222
+ text: part.text
223
+ });
224
+ break;
225
+ case "file":
226
+ if (part.mediaType.startsWith("image/")) {
227
+ const url = part.data instanceof URL ? part.data.toString() : `data:${part.mediaType === "image/*" ? "image/jpeg" : part.mediaType};base64,${convertToBase64(part.data)}`;
228
+ parts.push({
229
+ type: "image_url",
230
+ image_url: { url }
231
+ });
232
+ }
233
+ break;
234
+ }
235
+ if (parts.length === 1 && parts[0].type === "text") messages.push({
236
+ role: "user",
237
+ content: parts[0].text
238
+ });
239
+ else messages.push({
240
+ role: "user",
241
+ content: parts
242
+ });
243
+ break;
244
+ }
245
+ case "assistant": {
246
+ let text = "";
247
+ const toolCalls = [];
248
+ for (const part of content) switch (part.type) {
249
+ case "text":
250
+ case "reasoning":
251
+ text += part.text;
252
+ break;
253
+ case "tool-call":
254
+ toolCalls.push({
255
+ id: part.toolCallId,
256
+ type: "function",
257
+ function: {
258
+ name: part.toolName,
259
+ arguments: JSON.stringify(part.input)
260
+ }
261
+ });
262
+ break;
263
+ }
264
+ messages.push({
265
+ role: "assistant",
266
+ content: text || null,
267
+ ...toolCalls.length > 0 && { tool_calls: toolCalls }
268
+ });
269
+ break;
270
+ }
271
+ case "tool":
272
+ for (const part of content) {
273
+ if (part.type === "tool-approval-response") continue;
274
+ let outputValue;
275
+ switch (part.output.type) {
276
+ case "text":
277
+ case "error-text":
278
+ outputValue = part.output.value;
279
+ break;
280
+ case "execution-denied":
281
+ outputValue = part.output.reason ?? "Tool execution denied.";
282
+ break;
283
+ default: outputValue = JSON.stringify(part.output.value);
284
+ }
285
+ messages.push({
286
+ role: "tool",
287
+ tool_call_id: part.toolCallId,
288
+ content: outputValue
289
+ });
290
+ }
291
+ break;
292
+ }
293
+ return messages;
294
+ }
295
+ var DashScopeChatLanguageModel = class {
296
+ specificationVersion = "v3";
297
+ modelId;
298
+ config;
299
+ constructor(modelId, config) {
300
+ this.modelId = modelId;
301
+ this.config = config;
302
+ }
303
+ get provider() {
304
+ return this.config.provider;
305
+ }
306
+ get supportedUrls() {
307
+ return { "image/*": [/^https?:\/\/.*$/] };
308
+ }
309
+ async getArgs(options) {
310
+ const warnings = [];
311
+ if (options.frequencyPenalty != null) warnings.push({
312
+ type: "unsupported",
313
+ feature: "frequencyPenalty"
314
+ });
315
+ const dsOptions = await parseProviderOptions({
316
+ provider: "dashscope",
317
+ providerOptions: options.providerOptions,
318
+ schema: chatOptionsSchema
319
+ });
320
+ const { tools: apiTools, toolChoice, toolWarnings } = prepareTools({
321
+ tools: options.tools,
322
+ toolChoice: options.toolChoice
323
+ });
324
+ warnings.push(...toolWarnings);
325
+ return {
326
+ args: {
327
+ model: this.modelId,
328
+ messages: convertMessages(options.prompt),
329
+ ...options.maxOutputTokens != null && { max_tokens: options.maxOutputTokens },
330
+ ...options.temperature != null && { temperature: options.temperature },
331
+ ...options.topP != null && { top_p: options.topP },
332
+ ...options.topK != null && { top_k: options.topK },
333
+ ...options.presencePenalty != null && { presence_penalty: options.presencePenalty },
334
+ ...options.stopSequences?.length && { stop: options.stopSequences },
335
+ ...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" } },
344
+ ...apiTools != null && {
345
+ tools: apiTools,
346
+ tool_choice: toolChoice
347
+ },
348
+ ...dsOptions?.parallelToolCalls != null && { parallel_tool_calls: dsOptions.parallelToolCalls },
349
+ ...dsOptions?.enableThinking != null && { enable_thinking: dsOptions.enableThinking },
350
+ ...dsOptions?.thinkingBudget != null && { thinking_budget: dsOptions.thinkingBudget },
351
+ ...dsOptions?.enableSearch != null && { enable_search: dsOptions.enableSearch },
352
+ ...dsOptions?.searchStrategy != null && { search_options: { search_strategy: dsOptions.searchStrategy } },
353
+ ...dsOptions?.enableCodeInterpreter != null && { enable_code_interpreter: dsOptions.enableCodeInterpreter }
354
+ },
355
+ warnings
356
+ };
357
+ }
358
+ async doGenerate(options) {
359
+ const { args, warnings } = await this.getArgs(options);
360
+ const { responseHeaders, value: response } = await postJsonToApi({
361
+ url: `${this.config.baseURL}/chat/completions`,
362
+ headers: combineHeaders(this.config.headers(), options.headers),
363
+ body: args,
364
+ failedResponseHandler: failedResponseHandler$1,
365
+ successfulResponseHandler: createJsonResponseHandler(chatResponseSchema),
366
+ abortSignal: options.abortSignal,
367
+ fetch: this.config.fetch
368
+ });
369
+ const choice = response.choices[0];
370
+ const content = [];
371
+ if (choice.message.content != null && choice.message.content.length > 0) content.push({
372
+ type: "text",
373
+ text: choice.message.content
374
+ });
375
+ if (choice.message.reasoning_content != null && choice.message.reasoning_content.length > 0) content.push({
376
+ type: "reasoning",
377
+ text: choice.message.reasoning_content
378
+ });
379
+ if (choice.message.tool_calls != null) for (const toolCall of choice.message.tool_calls) content.push({
380
+ type: "tool-call",
381
+ toolCallId: toolCall.id,
382
+ toolName: toolCall.function.name,
383
+ input: toolCall.function.arguments
384
+ });
385
+ return {
386
+ content,
387
+ finishReason: {
388
+ unified: mapOpenAICompatibleFinishReason(choice.finish_reason),
389
+ raw: choice.finish_reason ?? void 0
390
+ },
391
+ usage: convertUsage$1(response.usage),
392
+ request: { body: JSON.stringify(args) },
393
+ 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,
397
+ headers: responseHeaders
398
+ },
399
+ warnings
400
+ };
401
+ }
402
+ async doStream(options) {
403
+ const { args, warnings } = await this.getArgs(options);
404
+ const body = {
405
+ ...args,
406
+ stream: true
407
+ };
408
+ const { responseHeaders, value: response } = await postJsonToApi({
409
+ url: `${this.config.baseURL}/chat/completions`,
410
+ headers: combineHeaders(this.config.headers(), options.headers),
411
+ body,
412
+ failedResponseHandler: failedResponseHandler$1,
413
+ successfulResponseHandler: createEventSourceResponseHandler(chatChunkSchema),
414
+ abortSignal: options.abortSignal,
415
+ fetch: this.config.fetch
416
+ });
417
+ let finishReason = {
418
+ unified: "other",
419
+ raw: void 0
420
+ };
421
+ let usage;
422
+ let isFirstChunk = true;
423
+ let activeText = false;
424
+ let activeReasoningId = null;
425
+ const toolCalls = [];
426
+ return {
427
+ stream: response.pipeThrough(new TransformStream({
428
+ start(controller) {
429
+ controller.enqueue({
430
+ type: "stream-start",
431
+ warnings
432
+ });
433
+ },
434
+ transform(chunk, controller) {
435
+ if (options.includeRawChunks) controller.enqueue({
436
+ type: "raw",
437
+ rawValue: chunk.rawValue
438
+ });
439
+ if (!chunk.success) {
440
+ controller.enqueue({
441
+ type: "error",
442
+ error: chunk.error
443
+ });
444
+ return;
445
+ }
446
+ const value = chunk.value;
447
+ if (isFirstChunk) {
448
+ isFirstChunk = false;
449
+ controller.enqueue({
450
+ 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
454
+ });
455
+ }
456
+ if (value.usage != null) usage = value.usage;
457
+ if (value.choices.length === 0) return;
458
+ const choice = value.choices[0];
459
+ const delta = choice.delta;
460
+ if (delta.reasoning_content != null && delta.reasoning_content.length > 0) {
461
+ if (activeReasoningId == null) {
462
+ if (activeText) {
463
+ controller.enqueue({
464
+ type: "text-end",
465
+ id: "0"
466
+ });
467
+ activeText = false;
468
+ }
469
+ activeReasoningId = generateId();
470
+ controller.enqueue({
471
+ type: "reasoning-start",
472
+ id: activeReasoningId
473
+ });
474
+ }
475
+ controller.enqueue({
476
+ type: "reasoning-delta",
477
+ id: activeReasoningId,
478
+ delta: delta.reasoning_content
479
+ });
480
+ }
481
+ if (delta.content != null && delta.content.length > 0) {
482
+ if (activeReasoningId != null) {
483
+ controller.enqueue({
484
+ type: "reasoning-end",
485
+ id: activeReasoningId
486
+ });
487
+ activeReasoningId = null;
488
+ }
489
+ if (!activeText) {
490
+ controller.enqueue({
491
+ type: "text-start",
492
+ id: "0"
493
+ });
494
+ activeText = true;
495
+ }
496
+ controller.enqueue({
497
+ type: "text-delta",
498
+ id: "0",
499
+ delta: delta.content
500
+ });
501
+ }
502
+ if (delta.tool_calls != null) {
503
+ if (activeReasoningId != null) {
504
+ controller.enqueue({
505
+ type: "reasoning-end",
506
+ id: activeReasoningId
507
+ });
508
+ activeReasoningId = null;
509
+ }
510
+ if (activeText) {
511
+ controller.enqueue({
512
+ type: "text-end",
513
+ id: "0"
514
+ });
515
+ activeText = false;
516
+ }
517
+ for (const toolCallDelta of delta.tool_calls) {
518
+ const index = toolCallDelta.index ?? toolCalls.length;
519
+ if (toolCalls[index] == null) {
520
+ if (toolCallDelta.id == null || toolCallDelta.function?.name == null) continue;
521
+ controller.enqueue({
522
+ type: "tool-input-start",
523
+ id: toolCallDelta.id,
524
+ toolName: toolCallDelta.function.name
525
+ });
526
+ toolCalls[index] = {
527
+ id: toolCallDelta.id,
528
+ function: {
529
+ name: toolCallDelta.function.name,
530
+ arguments: toolCallDelta.function.arguments ?? ""
531
+ },
532
+ hasFinished: false
533
+ };
534
+ const tc = toolCalls[index];
535
+ if (tc.function.arguments.length > 0) controller.enqueue({
536
+ type: "tool-input-delta",
537
+ id: tc.id,
538
+ delta: tc.function.arguments
539
+ });
540
+ if (isParsableJson(tc.function.arguments)) {
541
+ controller.enqueue({
542
+ type: "tool-input-end",
543
+ id: tc.id
544
+ });
545
+ controller.enqueue({
546
+ type: "tool-call",
547
+ toolCallId: tc.id,
548
+ toolName: tc.function.name,
549
+ input: tc.function.arguments
550
+ });
551
+ tc.hasFinished = true;
552
+ }
553
+ continue;
554
+ }
555
+ const tc = toolCalls[index];
556
+ if (tc.hasFinished) continue;
557
+ if (toolCallDelta.function?.arguments != null) {
558
+ tc.function.arguments += toolCallDelta.function.arguments;
559
+ controller.enqueue({
560
+ type: "tool-input-delta",
561
+ id: tc.id,
562
+ delta: toolCallDelta.function.arguments
563
+ });
564
+ }
565
+ if (isParsableJson(tc.function.arguments)) {
566
+ controller.enqueue({
567
+ type: "tool-input-end",
568
+ id: tc.id
569
+ });
570
+ controller.enqueue({
571
+ type: "tool-call",
572
+ toolCallId: tc.id,
573
+ toolName: tc.function.name,
574
+ input: tc.function.arguments
575
+ });
576
+ tc.hasFinished = true;
577
+ }
578
+ }
579
+ }
580
+ if (choice.finish_reason != null) finishReason = {
581
+ unified: mapOpenAICompatibleFinishReason(choice.finish_reason),
582
+ raw: choice.finish_reason
583
+ };
584
+ },
585
+ flush(controller) {
586
+ if (activeReasoningId != null) controller.enqueue({
587
+ type: "reasoning-end",
588
+ id: activeReasoningId
589
+ });
590
+ if (activeText) controller.enqueue({
591
+ type: "text-end",
592
+ id: "0"
593
+ });
594
+ controller.enqueue({
595
+ type: "finish",
596
+ finishReason,
597
+ usage: convertUsage$1(usage)
598
+ });
599
+ }
600
+ })),
601
+ request: { body: JSON.stringify(body) },
602
+ response: { headers: responseHeaders }
603
+ };
604
+ }
605
+ };
606
+ //#endregion
607
+ //#region src/responses.ts
608
+ const responsesOptionsSchema = zodSchema(z.object({
609
+ enableThinking: z.boolean().optional(),
610
+ reasoning: z.object({ effort: z.enum([
611
+ "none",
612
+ "minimal",
613
+ "low",
614
+ "medium",
615
+ "high"
616
+ ]) }).optional(),
617
+ previousResponseId: z.string().optional(),
618
+ conversation: z.string().optional(),
619
+ instructions: z.string().optional(),
620
+ includeUsage: z.boolean().optional()
621
+ }));
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
+ const responseSchema = zodSchema(z.object({
628
+ id: z.string(),
629
+ created_at: z.number().optional(),
630
+ object: z.literal("response"),
631
+ model: z.string().optional(),
632
+ status: z.string().optional(),
633
+ output: z.array(z.record(z.string(), z.unknown())).optional(),
634
+ usage: z.object({
635
+ input_tokens: z.number(),
636
+ output_tokens: z.number(),
637
+ total_tokens: z.number(),
638
+ input_tokens_details: z.object({ cached_tokens: z.number() }).optional(),
639
+ output_tokens_details: z.object({ reasoning_tokens: z.number() }).optional()
640
+ }).optional(),
641
+ error: z.object({ message: z.string() }).nullable().optional()
642
+ }).loose());
643
+ 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
+ function mapFinishReason(status) {
680
+ switch (status) {
681
+ case "completed": return {
682
+ unified: "stop",
683
+ raw: status
684
+ };
685
+ case "incomplete": return {
686
+ unified: "length",
687
+ raw: status
688
+ };
689
+ case "failed":
690
+ case "cancelled": return {
691
+ unified: "error",
692
+ raw: status
693
+ };
694
+ default: return {
695
+ unified: "other",
696
+ raw: status
697
+ };
698
+ }
699
+ }
700
+ function mapToolChoice(toolChoice) {
701
+ switch (toolChoice.type) {
702
+ case "auto": return "auto";
703
+ case "none": return "none";
704
+ case "required": return "required";
705
+ case "tool": return {
706
+ type: "allowed_tools",
707
+ mode: "auto",
708
+ tools: [{
709
+ type: "function",
710
+ name: toolChoice.toolName
711
+ }]
712
+ };
713
+ }
714
+ }
715
+ function convertOutput(output) {
716
+ const content = [];
717
+ for (const item of output) switch (item.type) {
718
+ case "message": {
719
+ const parts = item.content;
720
+ if (parts) {
721
+ for (const part of parts) if (part.type === "output_text" && typeof part.text === "string") content.push({
722
+ type: "text",
723
+ text: part.text
724
+ });
725
+ }
726
+ break;
727
+ }
728
+ case "reasoning": {
729
+ const summary = item.summary;
730
+ if (summary) {
731
+ for (const s of summary) if (s.text) content.push({
732
+ type: "reasoning",
733
+ text: s.text
734
+ });
735
+ }
736
+ break;
737
+ }
738
+ case "function_call":
739
+ content.push({
740
+ type: "tool-call",
741
+ toolCallId: item.call_id ?? "",
742
+ toolName: item.name ?? "",
743
+ input: item.arguments,
744
+ providerExecuted: false
745
+ });
746
+ break;
747
+ case "web_search_call": {
748
+ const action = item.action;
749
+ const sources = action?.sources;
750
+ if (sources) {
751
+ for (const source of sources) if (source.url) content.push({
752
+ type: "source",
753
+ sourceType: "url",
754
+ id: item.id ?? "",
755
+ url: source.url,
756
+ title: source.title
757
+ });
758
+ }
759
+ content.push({
760
+ type: "tool-call",
761
+ toolCallId: item.id ?? "",
762
+ toolName: "web_search",
763
+ input: JSON.stringify({
764
+ query: action?.query,
765
+ sources
766
+ }),
767
+ providerExecuted: true
768
+ });
769
+ break;
770
+ }
771
+ case "code_interpreter_call":
772
+ content.push({
773
+ type: "tool-call",
774
+ toolCallId: item.id ?? "",
775
+ toolName: "code_interpreter",
776
+ input: JSON.stringify({
777
+ code: item.code,
778
+ outputs: item.outputs,
779
+ containerId: item.container_id
780
+ }),
781
+ providerExecuted: true
782
+ });
783
+ break;
784
+ case "web_extractor_call":
785
+ content.push({
786
+ type: "tool-call",
787
+ toolCallId: item.id ?? "",
788
+ toolName: "web_extractor",
789
+ input: JSON.stringify({
790
+ urls: item.urls,
791
+ goal: item.goal
792
+ }),
793
+ providerExecuted: true
794
+ });
795
+ if (item.output) content.push({
796
+ type: "tool-result",
797
+ toolCallId: item.id ?? "",
798
+ toolName: "web_extractor",
799
+ result: item.output
800
+ });
801
+ break;
802
+ case "file_search_call":
803
+ content.push({
804
+ type: "tool-call",
805
+ toolCallId: item.id ?? "",
806
+ toolName: "file_search",
807
+ input: JSON.stringify({
808
+ queries: item.queries,
809
+ results: item.results
810
+ }),
811
+ providerExecuted: true
812
+ });
813
+ break;
814
+ case "web_search_image_call":
815
+ content.push({
816
+ type: "tool-call",
817
+ toolCallId: item.id ?? "",
818
+ toolName: "web_search_image",
819
+ input: JSON.stringify({
820
+ name: item.name,
821
+ arguments: item.arguments
822
+ }),
823
+ providerExecuted: true
824
+ });
825
+ if (item.output) content.push({
826
+ type: "tool-result",
827
+ toolCallId: item.id ?? "",
828
+ toolName: "web_search_image",
829
+ result: item.output
830
+ });
831
+ break;
832
+ case "image_search_call":
833
+ content.push({
834
+ type: "tool-call",
835
+ toolCallId: item.id ?? "",
836
+ toolName: "image_search",
837
+ input: JSON.stringify({
838
+ name: item.name,
839
+ arguments: item.arguments
840
+ }),
841
+ providerExecuted: true
842
+ });
843
+ if (item.output) content.push({
844
+ type: "tool-result",
845
+ toolCallId: item.id ?? "",
846
+ toolName: "image_search",
847
+ result: item.output
848
+ });
849
+ break;
850
+ case "mcp_call": {
851
+ const toolName = item.name ?? item.server_label ?? "mcp";
852
+ content.push({
853
+ type: "tool-call",
854
+ toolCallId: item.id ?? "",
855
+ toolName,
856
+ input: item.arguments ?? "{}",
857
+ providerExecuted: true
858
+ });
859
+ if (item.output) content.push({
860
+ type: "tool-result",
861
+ toolCallId: item.id ?? "",
862
+ toolName,
863
+ result: item.output
864
+ });
865
+ break;
866
+ }
867
+ }
868
+ return content;
869
+ }
870
+ function prepareTools$1(tools) {
871
+ if (!tools?.length) return [];
872
+ const apiTools = [];
873
+ for (const tool of tools) if (tool.type === "provider") switch (tool.id) {
874
+ case "dashscope.web_search":
875
+ apiTools.push({ type: "web_search" });
876
+ break;
877
+ case "dashscope.code_interpreter":
878
+ apiTools.push({ type: "code_interpreter" });
879
+ break;
880
+ case "dashscope.web_extractor":
881
+ apiTools.push({ type: "web_extractor" });
882
+ break;
883
+ case "dashscope.file_search": {
884
+ const args = tool.args;
885
+ apiTools.push({
886
+ type: "file_search",
887
+ vector_store_ids: args.vectorStoreIds
888
+ });
889
+ break;
890
+ }
891
+ case "dashscope.web_search_image":
892
+ apiTools.push({ type: "web_search_image" });
893
+ break;
894
+ case "dashscope.image_search":
895
+ apiTools.push({ type: "image_search" });
896
+ break;
897
+ case "dashscope.mcp": {
898
+ const args = tool.args;
899
+ apiTools.push({
900
+ type: "mcp",
901
+ server_protocol: args.serverProtocol,
902
+ server_label: args.serverLabel,
903
+ server_url: args.serverUrl,
904
+ ...args.serverDescription && { server_description: args.serverDescription },
905
+ ...args.headers && { headers: args.headers }
906
+ });
907
+ break;
908
+ }
909
+ }
910
+ else apiTools.push({
911
+ type: "function",
912
+ name: tool.name,
913
+ ...tool.description && { description: tool.description },
914
+ parameters: tool.inputSchema
915
+ });
916
+ return apiTools;
917
+ }
918
+ function convertFilePart(part) {
919
+ const data = part.data;
920
+ if (data instanceof URL) return {
921
+ type: "input_image",
922
+ image_url: data.toString()
923
+ };
924
+ if (typeof data === "string") {
925
+ if (data.startsWith("data:")) return {
926
+ type: "input_image",
927
+ image_url: data
928
+ };
929
+ return {
930
+ type: "input_image",
931
+ image_url: `data:${part.mediaType};base64,${data}`
932
+ };
933
+ }
934
+ }
935
+ function convertToolResultOutput(output) {
936
+ if (typeof output === "string") return output;
937
+ if (output && typeof output === "object" && "type" in output && output.type === "text") return output.value;
938
+ return JSON.stringify(output);
939
+ }
940
+ function convertInput(prompt) {
941
+ const input = [];
942
+ for (const message of prompt) {
943
+ const { role, content } = message;
944
+ if (typeof content === "string") {
945
+ input.push({
946
+ role,
947
+ content
948
+ });
949
+ continue;
950
+ }
951
+ const textParts = [];
952
+ const fileParts = [];
953
+ const functionCalls = [];
954
+ const functionOutputs = [];
955
+ for (const part of content) switch (part.type) {
956
+ case "text":
957
+ textParts.push(part.text);
958
+ break;
959
+ case "file": {
960
+ const filePart = convertFilePart(part);
961
+ if (filePart) fileParts.push(filePart);
962
+ break;
963
+ }
964
+ case "reasoning": break;
965
+ case "tool-call": {
966
+ const callPart = part;
967
+ functionCalls.push({
968
+ type: "function_call",
969
+ name: callPart.toolName,
970
+ arguments: typeof callPart.input === "string" ? callPart.input : JSON.stringify(callPart.input),
971
+ call_id: callPart.toolCallId
972
+ });
973
+ break;
974
+ }
975
+ case "tool-result": {
976
+ const resultPart = part;
977
+ functionOutputs.push({
978
+ type: "function_call_output",
979
+ call_id: resultPart.toolCallId,
980
+ output: convertToolResultOutput(resultPart.output)
981
+ });
982
+ break;
983
+ }
984
+ }
985
+ const messageParts = [...textParts.map((t) => ({
986
+ type: "text",
987
+ text: t
988
+ })), ...fileParts];
989
+ if (messageParts.length > 0) if (messageParts.length === 1 && textParts.length === 1) input.push({
990
+ role,
991
+ content: textParts[0]
992
+ });
993
+ else input.push({
994
+ role,
995
+ content: messageParts
996
+ });
997
+ input.push(...functionCalls, ...functionOutputs);
998
+ }
999
+ return input;
1000
+ }
1001
+ var DashScopeResponsesLanguageModel = class {
1002
+ specificationVersion = "v3";
1003
+ modelId;
1004
+ config;
1005
+ constructor(modelId, config) {
1006
+ this.modelId = modelId;
1007
+ this.config = config;
1008
+ }
1009
+ get provider() {
1010
+ return this.config.provider;
1011
+ }
1012
+ get supportedUrls() {
1013
+ return {};
1014
+ }
1015
+ async getArgs(options) {
1016
+ const warnings = [];
1017
+ if (options.topK != null) warnings.push({
1018
+ type: "unsupported",
1019
+ feature: "topK"
1020
+ });
1021
+ const dsOptions = await parseProviderOptions({
1022
+ provider: "dashscope",
1023
+ providerOptions: options.providerOptions,
1024
+ schema: responsesOptionsSchema
1025
+ });
1026
+ const tools = prepareTools$1(options.tools);
1027
+ const input = convertInput(options.prompt);
1028
+ return {
1029
+ args: {
1030
+ model: this.modelId,
1031
+ input,
1032
+ ...options.temperature != null && { temperature: options.temperature },
1033
+ ...options.topP != null && { top_p: options.topP },
1034
+ ...options.maxOutputTokens != null && { max_output_tokens: options.maxOutputTokens },
1035
+ ...options.stopSequences?.length && { stop: options.stopSequences },
1036
+ ...tools.length > 0 && { tools },
1037
+ ...options.toolChoice && { tool_choice: mapToolChoice(options.toolChoice) },
1038
+ ...dsOptions?.enableThinking != null && { enable_thinking: dsOptions.enableThinking },
1039
+ ...dsOptions?.reasoning != null && { reasoning: dsOptions.reasoning },
1040
+ ...dsOptions?.previousResponseId && { previous_response_id: dsOptions.previousResponseId },
1041
+ ...dsOptions?.conversation && { conversation: dsOptions.conversation },
1042
+ ...dsOptions?.instructions && { instructions: dsOptions.instructions }
1043
+ },
1044
+ warnings
1045
+ };
1046
+ }
1047
+ async doGenerate(options) {
1048
+ const { args: body, warnings } = await this.getArgs(options);
1049
+ const { responseHeaders, value: response } = await postJsonToApi({
1050
+ url: `${this.config.baseURL}/responses`,
1051
+ headers: combineHeaders(this.config.headers(), options.headers),
1052
+ body,
1053
+ failedResponseHandler,
1054
+ successfulResponseHandler: createJsonResponseHandler(responseSchema),
1055
+ abortSignal: options.abortSignal,
1056
+ fetch: this.config.fetch
1057
+ });
1058
+ if (response.error) throw new Error(`DashScope Responses API error: ${response.error.message}`);
1059
+ const content = convertOutput(response.output ?? []);
1060
+ const hasToolCall = content.some((c) => c.type === "tool-call" && "providerExecuted" in c && !c.providerExecuted);
1061
+ let finishReason = mapFinishReason(response.status);
1062
+ if (hasToolCall && finishReason.unified === "stop") finishReason = {
1063
+ unified: "tool-calls",
1064
+ raw: response.status
1065
+ };
1066
+ return {
1067
+ content,
1068
+ finishReason,
1069
+ usage: convertUsage(response.usage),
1070
+ request: { body },
1071
+ response: {
1072
+ id: response.id ?? void 0,
1073
+ headers: responseHeaders
1074
+ },
1075
+ warnings,
1076
+ providerMetadata: response.id ? { dashscope: {
1077
+ responseId: response.id,
1078
+ ...response.model && { model: response.model },
1079
+ ...response.created_at && { createdAt: response.created_at }
1080
+ } } : void 0
1081
+ };
1082
+ }
1083
+ async doStream(options) {
1084
+ const { args: body, warnings } = await this.getArgs(options);
1085
+ const { responseHeaders, value: response } = await postJsonToApi({
1086
+ url: `${this.config.baseURL}/responses`,
1087
+ headers: combineHeaders(this.config.headers(), options.headers),
1088
+ body: {
1089
+ ...body,
1090
+ stream: true
1091
+ },
1092
+ failedResponseHandler,
1093
+ successfulResponseHandler: createEventSourceResponseHandler(streamChunkSchema),
1094
+ abortSignal: options.abortSignal,
1095
+ fetch: this.config.fetch
1096
+ });
1097
+ let finishReason;
1098
+ let usage;
1099
+ return {
1100
+ stream: response.pipeThrough(new TransformStream({
1101
+ start(controller) {
1102
+ controller.enqueue({
1103
+ type: "stream-start",
1104
+ warnings
1105
+ });
1106
+ },
1107
+ transform(chunk, controller) {
1108
+ if (!chunk.success) {
1109
+ finishReason = {
1110
+ unified: "error",
1111
+ raw: void 0
1112
+ };
1113
+ controller.enqueue({
1114
+ type: "error",
1115
+ error: chunk.error
1116
+ });
1117
+ return;
1118
+ }
1119
+ const val = chunk.value;
1120
+ switch (val.type) {
1121
+ case "response.output_text.delta":
1122
+ controller.enqueue({
1123
+ type: "text-delta",
1124
+ id: String(val.output_index ?? 0),
1125
+ delta: val.delta ?? ""
1126
+ });
1127
+ break;
1128
+ case "response.reasoning_summary_text.delta":
1129
+ controller.enqueue({
1130
+ type: "reasoning-delta",
1131
+ id: String(val.output_index ?? 0),
1132
+ delta: val.delta ?? ""
1133
+ });
1134
+ break;
1135
+ case "response.output_item.added": {
1136
+ const item = val.item;
1137
+ if (item?.type === "function_call") controller.enqueue({
1138
+ type: "tool-input-start",
1139
+ id: item.id ?? "",
1140
+ toolName: item.name ?? ""
1141
+ });
1142
+ break;
1143
+ }
1144
+ case "response.mcp_call_arguments.delta":
1145
+ controller.enqueue({
1146
+ type: "tool-input-delta",
1147
+ id: val.item_id ?? "",
1148
+ delta: val.delta ?? ""
1149
+ });
1150
+ break;
1151
+ case "response.completed": {
1152
+ const resp = val.response;
1153
+ finishReason = mapFinishReason(resp?.status);
1154
+ if (resp?.usage) usage = convertUsage(resp.usage);
1155
+ if (resp?.id) controller.enqueue({
1156
+ type: "response-metadata",
1157
+ id: resp.id,
1158
+ modelId: resp.model,
1159
+ timestamp: resp.created_at ? /* @__PURE__ */ new Date(resp.created_at * 1e3) : void 0
1160
+ });
1161
+ break;
1162
+ }
1163
+ }
1164
+ },
1165
+ flush(controller) {
1166
+ if (finishReason || usage) controller.enqueue({
1167
+ type: "finish",
1168
+ usage: usage ?? {
1169
+ inputTokens: {
1170
+ total: 0,
1171
+ noCache: void 0,
1172
+ cacheRead: void 0,
1173
+ cacheWrite: void 0
1174
+ },
1175
+ outputTokens: {
1176
+ total: 0,
1177
+ text: void 0,
1178
+ reasoning: void 0
1179
+ }
1180
+ },
1181
+ finishReason: finishReason ?? {
1182
+ unified: "stop",
1183
+ raw: void 0
1184
+ }
1185
+ });
1186
+ }
1187
+ })),
1188
+ response: { headers: responseHeaders }
1189
+ };
1190
+ }
1191
+ };
1192
+ //#endregion
1193
+ //#region src/provider.ts
1194
+ 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 ?? "");
1198
+ 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");
1199
+ const apiKey = rest.apiKey ?? process.env.DASHSCOPE_API_KEY;
1200
+ const getHeaders = () => {
1201
+ const headers = {};
1202
+ if (apiKey) headers["Authorization"] = `Bearer ${apiKey}`;
1203
+ if (rest.headers) Object.assign(headers, rest.headers);
1204
+ return headers;
1205
+ };
1206
+ const chatConfig = {
1207
+ provider: "dashscope",
1208
+ baseURL,
1209
+ headers: getHeaders,
1210
+ fetch: rest.fetch,
1211
+ includeUsage
1212
+ };
1213
+ const createChatModel = (modelId) => new DashScopeChatLanguageModel(modelId, chatConfig);
1214
+ const createResponsesModel = (modelId) => new DashScopeResponsesLanguageModel(modelId, {
1215
+ provider: "dashscope.responses",
1216
+ baseURL,
1217
+ headers: getHeaders,
1218
+ fetch: rest.fetch
1219
+ });
1220
+ const responses = Object.assign(createResponsesModel, { tools: responsesTools });
1221
+ return Object.assign(createChatModel, {
1222
+ languageModel: createChatModel,
1223
+ chatOptions: (chatOpts) => ({ providerOptions: { dashscope: chatOpts } }),
1224
+ responsesOptions: (responsesOpts) => ({ providerOptions: { dashscope: responsesOpts } }),
1225
+ responses
1226
+ });
1227
+ }
1228
+ //#endregion
1229
+ //#region src/index.ts
1230
+ const dashscope = createDashScope();
1231
+ //#endregion
1232
+ export { DASHSCOPE_REGION_BASE_URLS, createDashScope, dashscope, responsesTools };