@ai-sdk/alibaba 1.0.34 → 1.0.36

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
@@ -22,7 +22,6 @@ import {
22
22
  createEventSourceResponseHandler,
23
23
  createJsonResponseHandler,
24
24
  generateId,
25
- isParsableJson,
26
25
  parseProviderOptions,
27
26
  postJsonToApi
28
27
  } from "@ai-sdk/provider-utils";
@@ -208,7 +207,7 @@ function convertToAlibabaChatMessages({
208
207
  contentValue = output.value;
209
208
  break;
210
209
  case "execution-denied":
211
- contentValue = (_b = output.reason) != null ? _b : "Tool execution denied.";
210
+ contentValue = (_b = output.reason) != null ? _b : "Tool call execution denied.";
212
211
  break;
213
212
  case "content":
214
213
  case "json":
@@ -556,19 +555,6 @@ var AlibabaLanguageModel = class {
556
555
  delta: toolCall2.function.arguments
557
556
  });
558
557
  }
559
- if (isParsableJson(toolCall2.function.arguments)) {
560
- controller.enqueue({
561
- type: "tool-input-end",
562
- id: toolCall2.id
563
- });
564
- controller.enqueue({
565
- type: "tool-call",
566
- toolCallId: toolCall2.id,
567
- toolName: toolCall2.function.name,
568
- input: toolCall2.function.arguments
569
- });
570
- toolCall2.hasFinished = true;
571
- }
572
558
  continue;
573
559
  }
574
560
  const toolCall = toolCalls[index];
@@ -583,19 +569,6 @@ var AlibabaLanguageModel = class {
583
569
  delta: toolCallDelta.function.arguments
584
570
  });
585
571
  }
586
- if (isParsableJson(toolCall.function.arguments)) {
587
- controller.enqueue({
588
- type: "tool-input-end",
589
- id: toolCall.id
590
- });
591
- controller.enqueue({
592
- type: "tool-call",
593
- toolCallId: toolCall.id,
594
- toolName: toolCall.function.name,
595
- input: toolCall.function.arguments
596
- });
597
- toolCall.hasFinished = true;
598
- }
599
572
  }
600
573
  }
601
574
  if (choice.finish_reason != null) {
@@ -615,6 +588,21 @@ var AlibabaLanguageModel = class {
615
588
  if (activeText) {
616
589
  controller.enqueue({ type: "text-end", id: "0" });
617
590
  }
591
+ for (const toolCall of toolCalls) {
592
+ if (!toolCall.hasFinished) {
593
+ controller.enqueue({
594
+ type: "tool-input-end",
595
+ id: toolCall.id
596
+ });
597
+ controller.enqueue({
598
+ type: "tool-call",
599
+ toolCallId: toolCall.id,
600
+ toolName: toolCall.function.name,
601
+ input: toolCall.function.arguments
602
+ });
603
+ toolCall.hasFinished = true;
604
+ }
605
+ }
618
606
  controller.enqueue({
619
607
  type: "finish",
620
608
  finishReason,
@@ -855,6 +843,7 @@ import {
855
843
  } from "@ai-sdk/provider";
856
844
  import {
857
845
  combineHeaders as combineHeaders3,
846
+ convertImageModelFileToDataUri,
858
847
  convertUint8ArrayToBase64,
859
848
  createJsonErrorResponseHandler as createJsonErrorResponseHandler3,
860
849
  createJsonResponseHandler as createJsonResponseHandler3,
@@ -877,6 +866,18 @@ var alibabaVideoModelOptionsSchema = lazySchema(
877
866
  watermark: z6.boolean().nullish(),
878
867
  audio: z6.boolean().nullish(),
879
868
  referenceUrls: z6.array(z6.string()).nullish(),
869
+ media: z6.array(
870
+ z6.object({
871
+ type: z6.enum([
872
+ "reference_image",
873
+ "reference_video",
874
+ "first_frame"
875
+ ]),
876
+ url: z6.string(),
877
+ referenceVoice: z6.string().nullish()
878
+ })
879
+ ).nullish(),
880
+ ratio: z6.enum(["16:9", "9:16", "1:1", "4:3", "3:4"]).nullish(),
880
881
  pollIntervalMs: z6.number().positive().nullish(),
881
882
  pollTimeoutMs: z6.number().positive().nullish()
882
883
  }).passthrough()
@@ -924,6 +925,38 @@ function detectMode(modelId) {
924
925
  if (modelId.includes("-r2v")) return "r2v";
925
926
  return "t2v";
926
927
  }
928
+ function isWan27Model(modelId) {
929
+ return modelId.startsWith("wan2.7");
930
+ }
931
+ var resolutionTierMap = {
932
+ "1280x720": "720P",
933
+ "720x1280": "720P",
934
+ "960x960": "720P",
935
+ "1088x832": "720P",
936
+ "832x1088": "720P",
937
+ "1920x1080": "1080P",
938
+ "1080x1920": "1080P",
939
+ "1440x1440": "1080P",
940
+ "1632x1248": "1080P",
941
+ "1248x1632": "1080P",
942
+ "832x480": "480P",
943
+ "480x832": "480P",
944
+ "624x624": "480P"
945
+ };
946
+ var supportedRatios = /* @__PURE__ */ new Set(["16:9", "9:16", "1:1", "4:3", "3:4"]);
947
+ function deriveRatioFromResolution(resolution) {
948
+ const [width, height] = resolution.split("x").map(Number);
949
+ if (!Number.isInteger(width) || !Number.isInteger(height) || width <= 0 || height <= 0) {
950
+ return void 0;
951
+ }
952
+ let a = width;
953
+ let b = height;
954
+ while (b !== 0) {
955
+ [a, b] = [b, a % b];
956
+ }
957
+ const ratio = `${width / a}:${height / a}`;
958
+ return supportedRatios.has(ratio) ? ratio : void 0;
959
+ }
927
960
  function fileToImageString(file) {
928
961
  if (file.type === "url") {
929
962
  return file.url;
@@ -938,6 +971,47 @@ function resolveStartImage(options) {
938
971
  var _a;
939
972
  return (_a = getFirstFrameImage(options)) != null ? _a : options.image;
940
973
  }
974
+ function isVideoUrl(url) {
975
+ return /\.(mp4|mov)([?#]|$)/i.test(url);
976
+ }
977
+ function resolveMedia(options, alibabaOptions, warnings) {
978
+ var _a;
979
+ if ((alibabaOptions == null ? void 0 : alibabaOptions.media) != null && alibabaOptions.media.length > 0) {
980
+ return alibabaOptions.media.map((item) => ({
981
+ type: item.type,
982
+ url: item.url,
983
+ ...item.referenceVoice != null ? { reference_voice: item.referenceVoice } : {}
984
+ }));
985
+ }
986
+ const media = [];
987
+ for (const reference of (_a = options.inputReferences) != null ? _a : []) {
988
+ if (reference.type === "url") {
989
+ media.push({
990
+ type: isVideoUrl(reference.url) ? "reference_video" : "reference_image",
991
+ url: reference.url
992
+ });
993
+ } else if (reference.mediaType.startsWith("image/")) {
994
+ media.push({
995
+ type: "reference_image",
996
+ url: convertImageModelFileToDataUri(reference)
997
+ });
998
+ } else {
999
+ warnings.push({
1000
+ type: "unsupported",
1001
+ feature: "inputReferences",
1002
+ details: "Alibaba reference-to-video requires URL references for videos. Non-URL video reference was skipped."
1003
+ });
1004
+ }
1005
+ }
1006
+ const firstFrame = getFirstFrameImage(options);
1007
+ if (firstFrame != null) {
1008
+ media.push({
1009
+ type: "first_frame",
1010
+ url: convertImageModelFileToDataUri(firstFrame)
1011
+ });
1012
+ }
1013
+ return media.length > 0 ? media : void 0;
1014
+ }
941
1015
  function resolveReferenceUrls(options, alibabaOptions, warnings) {
942
1016
  var _a;
943
1017
  if (options.frameImages != null && options.frameImages.length > 0) {
@@ -971,7 +1045,7 @@ var AlibabaVideoModel = class {
971
1045
  return this.config.provider;
972
1046
  }
973
1047
  async doGenerate(options) {
974
- var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n;
1048
+ var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p;
975
1049
  const currentDate = (_c = (_b = (_a = this.config._internal) == null ? void 0 : _a.currentDate) == null ? void 0 : _b.call(_a)) != null ? _c : /* @__PURE__ */ new Date();
976
1050
  const warnings = [];
977
1051
  const mode = detectMode(this.modelId);
@@ -991,16 +1065,27 @@ var AlibabaVideoModel = class {
991
1065
  input.audio_url = alibabaOptions.audioUrl;
992
1066
  }
993
1067
  const startImage = resolveStartImage(options);
994
- const referenceUrls = resolveReferenceUrls(
995
- options,
996
- alibabaOptions,
997
- warnings
998
- );
1068
+ const wan27 = isWan27Model(this.modelId);
1069
+ const supportsRatio = wan27 && mode !== "i2v";
999
1070
  if (mode === "i2v" && startImage != null) {
1000
1071
  input.img_url = fileToImageString(startImage);
1001
1072
  }
1002
- if (mode === "r2v" && referenceUrls != null && referenceUrls.length > 0) {
1003
- input.reference_urls = referenceUrls;
1073
+ if (mode === "r2v") {
1074
+ if (wan27) {
1075
+ const media = resolveMedia(options, alibabaOptions, warnings);
1076
+ if (media != null) {
1077
+ input.media = media;
1078
+ }
1079
+ } else {
1080
+ const referenceUrls = resolveReferenceUrls(
1081
+ options,
1082
+ alibabaOptions,
1083
+ warnings
1084
+ );
1085
+ if (referenceUrls != null && referenceUrls.length > 0) {
1086
+ input.reference_urls = referenceUrls;
1087
+ }
1088
+ }
1004
1089
  }
1005
1090
  const lastFrame = (_e = (_d = options.frameImages) == null ? void 0 : _d.find(
1006
1091
  (frame) => frame.frameType === "last_frame"
@@ -1027,41 +1112,57 @@ var AlibabaVideoModel = class {
1027
1112
  parameters.seed = options.seed;
1028
1113
  }
1029
1114
  if (options.resolution != null) {
1030
- if (mode === "i2v") {
1031
- const resolutionMap = {
1032
- "1280x720": "720P",
1033
- "720x1280": "720P",
1034
- "960x960": "720P",
1035
- "1088x832": "720P",
1036
- "832x1088": "720P",
1037
- "1920x1080": "1080P",
1038
- "1080x1920": "1080P",
1039
- "1440x1440": "1080P",
1040
- "1632x1248": "1080P",
1041
- "1248x1632": "1080P",
1042
- "832x480": "480P",
1043
- "480x832": "480P",
1044
- "624x624": "480P"
1045
- };
1046
- parameters.resolution = resolutionMap[options.resolution] || options.resolution;
1115
+ if (mode === "i2v" || wan27) {
1116
+ const resolutionTier = resolutionTierMap[options.resolution] || options.resolution;
1117
+ if (wan27 && resolutionTier !== "720P" && resolutionTier !== "1080P") {
1118
+ warnings.push({
1119
+ type: "unsupported",
1120
+ feature: "resolution",
1121
+ details: `wan2.7 models only support 720P and 1080P resolutions. The resolution "${options.resolution}" was ignored.`
1122
+ });
1123
+ } else {
1124
+ parameters.resolution = resolutionTier;
1125
+ }
1047
1126
  } else {
1048
1127
  parameters.size = options.resolution.replace("x", "*");
1049
1128
  }
1050
1129
  }
1130
+ if (supportsRatio) {
1131
+ const ratio = (_g = (_f = alibabaOptions == null ? void 0 : alibabaOptions.ratio) != null ? _f : options.aspectRatio) != null ? _g : options.resolution != null ? deriveRatioFromResolution(options.resolution) : void 0;
1132
+ if (ratio != null) {
1133
+ parameters.ratio = ratio;
1134
+ }
1135
+ }
1051
1136
  if ((alibabaOptions == null ? void 0 : alibabaOptions.promptExtend) != null) {
1052
1137
  parameters.prompt_extend = alibabaOptions.promptExtend;
1053
1138
  }
1054
1139
  if ((alibabaOptions == null ? void 0 : alibabaOptions.shotType) != null) {
1055
- parameters.shot_type = alibabaOptions.shotType;
1140
+ if (wan27) {
1141
+ warnings.push({
1142
+ type: "unsupported",
1143
+ feature: "shotType",
1144
+ details: "wan2.7 models do not support the shotType option. Describe the shot structure in the prompt instead."
1145
+ });
1146
+ } else {
1147
+ parameters.shot_type = alibabaOptions.shotType;
1148
+ }
1056
1149
  }
1057
1150
  if ((alibabaOptions == null ? void 0 : alibabaOptions.watermark) != null) {
1058
1151
  parameters.watermark = alibabaOptions.watermark;
1059
1152
  }
1060
- const audio = (_f = options.generateAudio) != null ? _f : alibabaOptions == null ? void 0 : alibabaOptions.audio;
1153
+ const audio = (_h = options.generateAudio) != null ? _h : alibabaOptions == null ? void 0 : alibabaOptions.audio;
1061
1154
  if (audio != null) {
1062
- parameters.audio = audio;
1155
+ if (wan27) {
1156
+ warnings.push({
1157
+ type: "unsupported",
1158
+ feature: "generateAudio",
1159
+ details: "wan2.7 models always generate audio. The audio option was ignored."
1160
+ });
1161
+ } else {
1162
+ parameters.audio = audio;
1163
+ }
1063
1164
  }
1064
- if (options.aspectRatio) {
1165
+ if (options.aspectRatio && !supportsRatio) {
1065
1166
  warnings.push({
1066
1167
  type: "unsupported",
1067
1168
  feature: "aspectRatio",
@@ -1103,15 +1204,15 @@ var AlibabaVideoModel = class {
1103
1204
  abortSignal: options.abortSignal,
1104
1205
  fetch: this.config.fetch
1105
1206
  });
1106
- const taskId = (_g = createResponse.output) == null ? void 0 : _g.task_id;
1207
+ const taskId = (_i = createResponse.output) == null ? void 0 : _i.task_id;
1107
1208
  if (!taskId) {
1108
1209
  throw new AISDKError({
1109
1210
  name: "ALIBABA_VIDEO_GENERATION_ERROR",
1110
1211
  message: `No task_id returned from Alibaba API. Response: ${JSON.stringify(createResponse)}`
1111
1212
  });
1112
1213
  }
1113
- const pollIntervalMs = (_h = alibabaOptions == null ? void 0 : alibabaOptions.pollIntervalMs) != null ? _h : 5e3;
1114
- const pollTimeoutMs = (_i = alibabaOptions == null ? void 0 : alibabaOptions.pollTimeoutMs) != null ? _i : 6e5;
1214
+ const pollIntervalMs = (_j = alibabaOptions == null ? void 0 : alibabaOptions.pollIntervalMs) != null ? _j : 5e3;
1215
+ const pollTimeoutMs = (_k = alibabaOptions == null ? void 0 : alibabaOptions.pollTimeoutMs) != null ? _k : 6e5;
1115
1216
  const startTime = Date.now();
1116
1217
  let finalResponse;
1117
1218
  let responseHeaders;
@@ -1137,7 +1238,7 @@ var AlibabaVideoModel = class {
1137
1238
  fetch: this.config.fetch
1138
1239
  });
1139
1240
  responseHeaders = pollHeaders;
1140
- const taskStatus = (_j = statusResponse.output) == null ? void 0 : _j.task_status;
1241
+ const taskStatus = (_l = statusResponse.output) == null ? void 0 : _l.task_status;
1141
1242
  if (taskStatus === "SUCCEEDED") {
1142
1243
  finalResponse = statusResponse;
1143
1244
  break;
@@ -1145,11 +1246,11 @@ var AlibabaVideoModel = class {
1145
1246
  if (taskStatus === "FAILED" || taskStatus === "CANCELED") {
1146
1247
  throw new AISDKError({
1147
1248
  name: "ALIBABA_VIDEO_GENERATION_FAILED",
1148
- message: `Video generation ${taskStatus.toLowerCase()}. Task ID: ${taskId}. ${(_l = (_k = statusResponse.output) == null ? void 0 : _k.message) != null ? _l : ""}`
1249
+ message: `Video generation ${taskStatus.toLowerCase()}. Task ID: ${taskId}. ${(_n = (_m = statusResponse.output) == null ? void 0 : _m.message) != null ? _n : ""}`
1149
1250
  });
1150
1251
  }
1151
1252
  }
1152
- const videoUrl = (_m = finalResponse == null ? void 0 : finalResponse.output) == null ? void 0 : _m.video_url;
1253
+ const videoUrl = (_o = finalResponse == null ? void 0 : finalResponse.output) == null ? void 0 : _o.video_url;
1153
1254
  if (!videoUrl) {
1154
1255
  throw new AISDKError({
1155
1256
  name: "ALIBABA_VIDEO_GENERATION_ERROR",
@@ -1174,7 +1275,7 @@ var AlibabaVideoModel = class {
1174
1275
  alibaba: {
1175
1276
  taskId,
1176
1277
  videoUrl,
1177
- ...((_n = finalResponse == null ? void 0 : finalResponse.output) == null ? void 0 : _n.actual_prompt) ? { actualPrompt: finalResponse.output.actual_prompt } : {},
1278
+ ...((_p = finalResponse == null ? void 0 : finalResponse.output) == null ? void 0 : _p.actual_prompt) ? { actualPrompt: finalResponse.output.actual_prompt } : {},
1178
1279
  ...(finalResponse == null ? void 0 : finalResponse.usage) ? {
1179
1280
  usage: {
1180
1281
  duration: finalResponse.usage.duration,
@@ -1190,7 +1291,7 @@ var AlibabaVideoModel = class {
1190
1291
  };
1191
1292
 
1192
1293
  // src/version.ts
1193
- var VERSION = true ? "1.0.34" : "0.0.0-test";
1294
+ var VERSION = true ? "1.0.36" : "0.0.0-test";
1194
1295
 
1195
1296
  // src/alibaba-provider.ts
1196
1297
  function createAlibaba(options = {}) {