@shop-os/modelkit 0.2.9 → 0.2.11

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.js CHANGED
@@ -1,6 +1,14 @@
1
1
  // src/index.ts
2
2
  export * from "ai";
3
3
 
4
+ // src/types.ts
5
+ function hasAwsCredentials(aws) {
6
+ if (!aws || !aws.region) return false;
7
+ if (aws.apiKey) return true;
8
+ if (aws.credentialProvider) return true;
9
+ return Boolean(aws.accessKeyId && aws.secretAccessKey);
10
+ }
11
+
4
12
  // src/errors.ts
5
13
  var ModelKitError = class extends Error {
6
14
  code;
@@ -1470,6 +1478,7 @@ var VIDEO_MODELS = [
1470
1478
  },
1471
1479
  {
1472
1480
  // generateAudio defaults to false here (trigger-workflows); Space Builder defaults it to true.
1481
+ // omni_reference_task_type edit/extend: adaptive ratio, edit sends duration -1.
1473
1482
  id: "seedance-2.5",
1474
1483
  aliases: ["seedance-2-5", "dreamina-seedance-2-5-260628"],
1475
1484
  label: "Seedance 2.5",
@@ -1484,7 +1493,7 @@ var VIDEO_MODELS = [
1484
1493
  durations: { min: 4, max: 30 },
1485
1494
  references: { images: 30, videos: 10, audios: 10 },
1486
1495
  ratioIgnoredWith: ["firstFrame", "sourceVideo"],
1487
- supports: ["generateAudio", "seed", "lastFrame", "watermark"]
1496
+ supports: ["generateAudio", "seed", "lastFrame", "watermark", "taskType"]
1488
1497
  },
1489
1498
  defaults: {
1490
1499
  durationSeconds: 5,
@@ -1593,6 +1602,9 @@ var VIDEO_MODELS = [
1593
1602
  },
1594
1603
  {
1595
1604
  // mode standard/pro selects 720p/1080p; the endpoint takes no separate resolution.
1605
+ // Replicate: "Max 7 [images] without video, 4 with video"; 4K does not support
1606
+ // reference_video. No `videos` limit yet: the adapter sends no reference video,
1607
+ // so `imagesWithVideo` stays dormant until one is wired through.
1596
1608
  id: "kling-v3-omni-video",
1597
1609
  aliases: ["kwaivgi/kling-v3-omni-video", "kling-v3-omni"],
1598
1610
  label: "Kling V3 Omni",
@@ -1605,7 +1617,7 @@ var VIDEO_MODELS = [
1605
1617
  aspectRatios: [...KLING_RATIOS],
1606
1618
  resolutions: ["720p", "1080p"],
1607
1619
  durations: { min: 3, max: 15 },
1608
- references: { images: 7 },
1620
+ references: { images: 7, imagesWithVideo: 4 },
1609
1621
  supports: ["generateAudio", "lastFrame"]
1610
1622
  },
1611
1623
  defaults: { durationSeconds: 5, aspectRatio: "16:9", generateAudio: false, mode: "pro" },
@@ -1881,6 +1893,7 @@ var SupportedOptionSchema = z.enum([
1881
1893
  "upscale",
1882
1894
  "watermark",
1883
1895
  "safetyChecker",
1896
+ "taskType",
1884
1897
  "instrumental"
1885
1898
  ]);
1886
1899
  var UsageUnitSchema = z.enum([
@@ -1903,6 +1916,7 @@ var ProviderOptionValueSchema = z.lazy(
1903
1916
  var ProviderOptionsSchema = z.record(z.string(), z.record(z.string(), ProviderOptionValueSchema));
1904
1917
  var ReferenceLimitsSchema = z.looseObject({
1905
1918
  images: z.number().optional(),
1919
+ imagesWithVideo: z.number().optional(),
1906
1920
  videos: z.number().optional(),
1907
1921
  audios: z.number().optional(),
1908
1922
  total: z.number().optional(),
@@ -1964,6 +1978,7 @@ var DefaultsSchema = z.looseObject({
1964
1978
  promptExpansion: z.enum(["fast", "balanced", "quality"]).optional(),
1965
1979
  watermark: z.boolean().optional(),
1966
1980
  safetyChecker: z.boolean().optional(),
1981
+ taskType: z.enum(["reference", "edit", "extend"]).optional(),
1967
1982
  mode: z.enum(["standard", "pro"]).optional(),
1968
1983
  instrumental: z.boolean().optional()
1969
1984
  });
@@ -2030,7 +2045,18 @@ var CatalogModelSchemaBase = z.looseObject({
2030
2045
  });
2031
2046
  }
2032
2047
  });
2033
- var CatalogModelSchema = CatalogModelSchemaBase;
2048
+ var CatalogModelSchema = CatalogModelSchemaBase.superRefine(
2049
+ (row, ctx) => {
2050
+ const transport = row.providerOptions?.["modelkit"]?.["transport"];
2051
+ if (transport !== void 0 && transport !== "direct" && transport !== "bedrock") {
2052
+ ctx.addIssue({
2053
+ code: "custom",
2054
+ path: ["providerOptions", "modelkit", "transport"],
2055
+ message: 'transport must be "direct" or "bedrock"'
2056
+ });
2057
+ }
2058
+ }
2059
+ );
2034
2060
  var CatalogSchema = z.array(CatalogModelSchemaBase).superRefine((rows, ctx) => {
2035
2061
  const seenIds = /* @__PURE__ */ new Map();
2036
2062
  rows.forEach((row, index) => {
@@ -2523,6 +2549,9 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
2523
2549
  model,
2524
2550
  warnings
2525
2551
  );
2552
+ if (limits.imagesWithVideo !== void 0 && (limits.videos ?? 0) > 0 && videos.length > 0 && images.length > limits.imagesWithVideo) {
2553
+ images = trim("referenceImages", images, limits.imagesWithVideo, model, warnings);
2554
+ }
2526
2555
  if (limits.total !== void 0) {
2527
2556
  let over = images.length + videos.length + audios.length - limits.total;
2528
2557
  if (over > 0) {
@@ -2556,7 +2585,8 @@ function resolveVideoOptions(model, request, onUnsupported = "error") {
2556
2585
  "promptExpansion",
2557
2586
  "lastFrame",
2558
2587
  "watermark",
2559
- "safetyChecker"
2588
+ "safetyChecker",
2589
+ "taskType"
2560
2590
  ]);
2561
2591
  return { request: merged, warnings };
2562
2592
  }
@@ -2631,9 +2661,12 @@ var ADAPTER_KEYS = {
2631
2661
  function hasAll(keys, names) {
2632
2662
  if (!keys) return false;
2633
2663
  return names.every(
2634
- (n) => Boolean(keys[n]) && (n !== "higgsfield" || Boolean(keys.higgsfieldSecret))
2664
+ (n) => n === "aws" ? hasAwsCredentials(keys.aws) : Boolean(keys[n]) && (n !== "higgsfield" || Boolean(keys.higgsfieldSecret))
2635
2665
  );
2636
2666
  }
2667
+ function hasKey(keys, name) {
2668
+ return hasAll(keys, [name]);
2669
+ }
2637
2670
  function missingEnterpriseKeys(config, names) {
2638
2671
  return names.filter((name) => !hasAll(config.keys.enterprise, [name]));
2639
2672
  }
@@ -2670,6 +2703,22 @@ function keysFromEnv(env, prefix = "") {
2670
2703
  set("higgsfield", pick("HIGGSFIELD_API_KEY"));
2671
2704
  set("higgsfieldSecret", pick("HIGGSFIELD_API_SECRET"));
2672
2705
  set("cloudflare", pick("CLOUDFLARE_AI_GATEWAY_TOKEN", "CF_AIG_TOKEN"));
2706
+ const bearer = pick("AWS_BEARER_TOKEN_BEDROCK");
2707
+ const accessKeyId = pick("AWS_ACCESS_KEY_ID");
2708
+ const secretAccessKey = pick("AWS_SECRET_ACCESS_KEY");
2709
+ if (bearer || accessKeyId && secretAccessKey) {
2710
+ const aws = {
2711
+ region: env[`${prefix}BEDROCK_REGION`] || "us-east-1"
2712
+ };
2713
+ if (accessKeyId && secretAccessKey) {
2714
+ aws.accessKeyId = accessKeyId;
2715
+ aws.secretAccessKey = secretAccessKey;
2716
+ }
2717
+ const sessionToken = pick("AWS_SESSION_TOKEN");
2718
+ if (sessionToken) aws.sessionToken = sessionToken;
2719
+ if (bearer) aws.apiKey = bearer;
2720
+ keys.aws = aws;
2721
+ }
2673
2722
  return keys;
2674
2723
  }
2675
2724
 
@@ -3005,6 +3054,7 @@ function toGeneratedImage(image) {
3005
3054
  }
3006
3055
 
3007
3056
  // src/adapters/ai-sdk-text.ts
3057
+ import { createBedrockAnthropic } from "@ai-sdk/amazon-bedrock/anthropic";
3008
3058
  import { createAnthropic } from "@ai-sdk/anthropic";
3009
3059
  import { createGoogleGenerativeAI } from "@ai-sdk/google";
3010
3060
  import { createOpenAI } from "@ai-sdk/openai";
@@ -3056,16 +3106,47 @@ function detectTextProvider(modelId) {
3056
3106
  message: `ai-sdk-text cannot detect a provider for "${modelId}". Set providerOptions.provider to one of ${TEXT_PROVIDERS.join(", ")}.`
3057
3107
  });
3058
3108
  }
3059
- function textKeyName(model, _routing) {
3060
- return textProviderOf(model);
3109
+ function textKeyName(model, transport) {
3110
+ const provider = textProviderOf(model);
3111
+ return provider === "anthropic" && transport === "bedrock" ? "aws" : provider;
3061
3112
  }
3062
3113
  function textProviderOf(model) {
3063
3114
  const explicit = model.providerOptions?.["modelkit"]?.["provider"];
3064
3115
  return isTextProvider(explicit) ? explicit : detectTextProvider(model.providerModelId);
3065
3116
  }
3066
- function textUsesCloudflareGateway(model, routing) {
3117
+ function textUsesCloudflareGateway(model, routing, transport) {
3067
3118
  if (routing.text !== "cloudflare") return false;
3068
- return GATEWAY_SLUGS[textProviderOf(model)] !== void 0;
3119
+ const provider = textProviderOf(model);
3120
+ if (provider === "anthropic" && transport === "bedrock") return false;
3121
+ return GATEWAY_SLUGS[provider] !== void 0;
3122
+ }
3123
+ var BEDROCK_DATED_MODEL_IDS = {
3124
+ "claude-haiku-4-5": "anthropic.claude-haiku-4-5-20251001-v1:0",
3125
+ "claude-haiku-4-5-20251001": "anthropic.claude-haiku-4-5-20251001-v1:0",
3126
+ "claude-sonnet-4-5": "anthropic.claude-sonnet-4-5-20250929-v1:0",
3127
+ "claude-sonnet-4-5-20250929": "anthropic.claude-sonnet-4-5-20250929-v1:0"
3128
+ };
3129
+ var BEDROCK_PROFILE_PREFIXES = ["us.", "global.", "eu.", "jp.", "au.", "apac."];
3130
+ function toBedrockModelId(model, routing) {
3131
+ const profile = routing.bedrockProfile ?? "us";
3132
+ const override = model.providerOptions?.["modelkit"]?.["bedrockModelId"];
3133
+ if (typeof override === "string" && override.length > 0) {
3134
+ if (BEDROCK_PROFILE_PREFIXES.some((prefix) => override.startsWith(prefix))) return override;
3135
+ if (override.startsWith("anthropic.")) return `${profile}.${override}`;
3136
+ return override;
3137
+ }
3138
+ const id = model.providerModelId;
3139
+ if (BEDROCK_PROFILE_PREFIXES.some((prefix) => id.startsWith(prefix))) return id;
3140
+ const dated = BEDROCK_DATED_MODEL_IDS[id];
3141
+ if (dated) return `${profile}.${dated}`;
3142
+ if (id.startsWith("claude-")) return `${profile}.anthropic.${id}`;
3143
+ throw new ModelKitError({
3144
+ code: "unsupported_option",
3145
+ message: `No Bedrock model id for "${id}". Set providerOptions.modelkit.bedrockModelId on the catalog row.`,
3146
+ provider: "ai-sdk-text",
3147
+ model: model.id,
3148
+ retryable: false
3149
+ });
3069
3150
  }
3070
3151
  function nativeClientFor(provider) {
3071
3152
  switch (provider) {
@@ -3090,14 +3171,14 @@ function nativeClientFor(provider) {
3090
3171
  function resolveTextRoute(ctx) {
3091
3172
  const provider = textProviderOf(ctx.model);
3092
3173
  const mode = ctx.routing.text ?? "direct";
3093
- if (provider === "anthropic" && ctx.routing.anthropic === "bedrock") {
3094
- throw new ModelKitError({
3095
- code: "unsupported_option",
3096
- message: "ai-sdk-text has no Bedrock transport (@ai-sdk/amazon-bedrock is not installed). Pass the Bedrock model through catalogOverride with providerOptions.bedrockModel and resolve it outside the SDK.",
3097
- provider: "ai-sdk-text",
3098
- model: ctx.model.id,
3099
- retryable: false
3100
- });
3174
+ if (provider === "anthropic" && ctx.anthropicTransport === "bedrock") {
3175
+ return {
3176
+ provider,
3177
+ client: "bedrock-anthropic",
3178
+ modelId: toBedrockModelId(ctx.model, ctx.routing),
3179
+ keyName: "aws",
3180
+ canonicalModelId: ctx.model.id
3181
+ };
3101
3182
  }
3102
3183
  const compatBase = OPENAI_COMPATIBLE_BASE_URLS[provider];
3103
3184
  const route2 = {
@@ -3141,6 +3222,70 @@ function missingKey(ctx, name) {
3141
3222
  retryable: false
3142
3223
  });
3143
3224
  }
3225
+ function bedrockMiddleware(ctx, canonicalModelId) {
3226
+ let warned = false;
3227
+ return {
3228
+ specificationVersion: "v3",
3229
+ transformParams: async ({ params }) => {
3230
+ const anthropic = params.providerOptions?.["anthropic"];
3231
+ if (typeof anthropic !== "object" || anthropic === null || !("cacheControl" in anthropic))
3232
+ return params;
3233
+ if (!warned) {
3234
+ warned = true;
3235
+ ctx.logger.warn(
3236
+ `[modelkit] ${canonicalModelId} drops call-level providerOptions.anthropic.cacheControl: not supported on Bedrock, use message-level cacheControl`
3237
+ );
3238
+ }
3239
+ const { cacheControl: _dropped, ...rest } = anthropic;
3240
+ return {
3241
+ ...params,
3242
+ providerOptions: { ...params.providerOptions, anthropic: rest }
3243
+ };
3244
+ },
3245
+ // Bedrock echoes its own id for dated models (anthropic.claude-haiku-4-5-20251001-v1:0),
3246
+ // and consumers bill on response.modelId.
3247
+ wrapGenerate: async ({ doGenerate }) => {
3248
+ const result = await doGenerate();
3249
+ if (!result.response) return result;
3250
+ return { ...result, response: { ...result.response, modelId: canonicalModelId } };
3251
+ },
3252
+ wrapStream: async ({ doStream }) => {
3253
+ const result = await doStream();
3254
+ return {
3255
+ ...result,
3256
+ stream: result.stream.pipeThrough(
3257
+ new TransformStream({
3258
+ transform(part, controller) {
3259
+ controller.enqueue(
3260
+ part.type === "response-metadata" && part.modelId !== void 0 ? { ...part, modelId: canonicalModelId } : part
3261
+ );
3262
+ }
3263
+ })
3264
+ )
3265
+ };
3266
+ }
3267
+ };
3268
+ }
3269
+ function bedrockLanguageModel(ctx, route2) {
3270
+ const aws = ctx.keys.aws;
3271
+ if (!hasAwsCredentials(aws)) throw missingKey(ctx, "aws");
3272
+ const canonical = route2.canonicalModelId ?? ctx.model.id;
3273
+ const inner = createBedrockAnthropic({
3274
+ region: aws.region,
3275
+ fetch: ctx.fetch,
3276
+ ...aws.apiKey ? { apiKey: aws.apiKey } : aws.credentialProvider ? { credentialProvider: aws.credentialProvider } : aws.accessKeyId !== void 0 && aws.secretAccessKey !== void 0 ? {
3277
+ accessKeyId: aws.accessKeyId,
3278
+ secretAccessKey: aws.secretAccessKey,
3279
+ ...aws.sessionToken !== void 0 ? { sessionToken: aws.sessionToken } : {}
3280
+ } : {}
3281
+ })(route2.modelId);
3282
+ return wrapLanguageModel({
3283
+ model: inner,
3284
+ middleware: bedrockMiddleware(ctx, canonical),
3285
+ modelId: canonical,
3286
+ providerId: "anthropic.messages"
3287
+ });
3288
+ }
3144
3289
  function minimaxDefaults(params) {
3145
3290
  return params.responseFormat?.type === "json" ? { reasoning_split: true, thinking: { type: "disabled" } } : { reasoning_split: true };
3146
3291
  }
@@ -3179,8 +3324,11 @@ var aiSdkTextAdapter = {
3179
3324
  id: "ai-sdk-text",
3180
3325
  languageModel(ctx) {
3181
3326
  const route2 = resolveTextRoute(ctx);
3182
- const apiKey = ctx.keys[route2.keyName];
3183
- if (!apiKey) throw missingKey(ctx, route2.keyName);
3327
+ if (route2.client === "bedrock-anthropic") return bedrockLanguageModel(ctx, route2);
3328
+ const { keyName } = route2;
3329
+ if (keyName === "aws") throw missingKey(ctx, keyName);
3330
+ const apiKey = ctx.keys[keyName];
3331
+ if (!apiKey) throw missingKey(ctx, keyName);
3184
3332
  const settings = { apiKey, fetch: ctx.fetch };
3185
3333
  if (route2.baseURL !== void 0) settings.baseURL = route2.baseURL;
3186
3334
  if (route2.headers !== void 0) settings.headers = route2.headers;
@@ -3219,14 +3367,43 @@ var aiSdkTextAdapter = {
3219
3367
  }
3220
3368
  };
3221
3369
 
3370
+ // src/anthropic-transport.ts
3371
+ var ANTHROPIC_TRANSPORTS = ["direct", "bedrock"];
3372
+ function isAnthropicTransport(value) {
3373
+ return ANTHROPIC_TRANSPORTS.some((transport) => transport === value);
3374
+ }
3375
+ function preferredAnthropicTransport(model, routing) {
3376
+ const row = model.providerOptions?.["modelkit"]?.["transport"];
3377
+ if (isAnthropicTransport(row)) return row;
3378
+ return routing.anthropic ?? "direct";
3379
+ }
3380
+ function resolveAnthropicTransport(model, config, tier, warn) {
3381
+ if (model.adapter !== "ai-sdk-text" || textProviderOf(model) !== "anthropic") return void 0;
3382
+ const rowValue = model.providerOptions?.["modelkit"]?.["transport"];
3383
+ if (rowValue !== void 0 && !isAnthropicTransport(rowValue))
3384
+ warn(
3385
+ `[modelkit] ${model.id} has an unknown providerOptions.modelkit.transport "${String(rowValue)}"; ignoring it`
3386
+ );
3387
+ const preferred = preferredAnthropicTransport(model, config.routing ?? {});
3388
+ const usable = (transport) => {
3389
+ const name = transport === "bedrock" ? "aws" : "anthropic";
3390
+ return hasKey(config.keys.pro, name) || tier === "enterprise" && hasKey(config.keys.enterprise, name);
3391
+ };
3392
+ if (usable(preferred)) return preferred;
3393
+ const other = preferred === "bedrock" ? "direct" : "bedrock";
3394
+ if (!usable(other)) return preferred;
3395
+ warn(`[modelkit] ${model.id}: no credentials for the ${preferred} transport; using ${other}`);
3396
+ return other;
3397
+ }
3398
+
3222
3399
  // src/client.ts
3223
- function requiredKeys(model, config) {
3400
+ function requiredKeys(model, config, transport) {
3224
3401
  if (model.adapter === "fal" && config.routing?.fal === "cloudflare-passthrough")
3225
3402
  return ["cloudflare"];
3226
3403
  if (model.adapter === "ai-sdk-text") {
3227
3404
  const routing = config.routing ?? {};
3228
- const names = [textKeyName(model, routing)];
3229
- if (textUsesCloudflareGateway(model, routing)) names.push("cloudflare");
3405
+ const names = [textKeyName(model, transport)];
3406
+ if (textUsesCloudflareGateway(model, routing, transport)) names.push("cloudflare");
3230
3407
  return names;
3231
3408
  }
3232
3409
  return ADAPTER_KEYS[model.adapter];
@@ -3313,6 +3490,12 @@ function createModelKit(config, adapters) {
3313
3490
  const catalog = config.catalogOverride ? liveCatalog.withOverrides(config.catalogOverride) : liveCatalog;
3314
3491
  const logger = config.logger ?? console;
3315
3492
  const fetchImpl = config.fetch ?? globalThis.fetch;
3493
+ const transportWarnings = /* @__PURE__ */ new Set();
3494
+ function warnOnce(message) {
3495
+ if (transportWarnings.has(message)) return;
3496
+ transportWarnings.add(message);
3497
+ logger.warn(message);
3498
+ }
3316
3499
  function context(model, call, warnings) {
3317
3500
  const adapter = adapters[model.adapter];
3318
3501
  if (!adapter)
@@ -3321,7 +3504,8 @@ function createModelKit(config, adapters) {
3321
3504
  message: `No adapter registered for ${model.adapter}`,
3322
3505
  model: model.id
3323
3506
  });
3324
- const names = requiredKeys(model, config);
3507
+ const transport = resolveAnthropicTransport(model, config, call.tier, warnOnce);
3508
+ const names = requiredKeys(model, config, transport);
3325
3509
  if (call.tier === "enterprise") {
3326
3510
  const missing = missingEnterpriseKeys(config, names);
3327
3511
  if (missing.length > 0)
@@ -3340,6 +3524,7 @@ function createModelKit(config, adapters) {
3340
3524
  call,
3341
3525
  warnings
3342
3526
  };
3527
+ if (transport) ctx.anthropicTransport = transport;
3343
3528
  if (config.endpoints) ctx.endpoints = config.endpoints;
3344
3529
  if (call.signal) ctx.signal = call.signal;
3345
3530
  return { adapter, ctx };
@@ -3674,7 +3859,7 @@ function createModelKit(config, adapters) {
3674
3859
  async prepareMediaPart(modelId, ref, mediaType, call = {}) {
3675
3860
  const model = catalog.require(modelId);
3676
3861
  const { adapter, ctx } = context(model, call, []);
3677
- const fileStore = model.adapter === "ai-sdk-text" && textKeyName(model, config.routing ?? {}) === "google" ? adapters["google-genai"] : adapter;
3862
+ const fileStore = model.adapter === "ai-sdk-text" && textKeyName(model) === "google" ? adapters["google-genai"] : adapter;
3678
3863
  if (fileStore?.prepareMediaPart) return fileStore.prepareMediaPart(ref, mediaType, ctx);
3679
3864
  return "url" in ref ? { type: "file", data: ref.url, mediaType } : { type: "file", data: ref.bytes, mediaType };
3680
3865
  },
@@ -4004,9 +4189,22 @@ function seedanceErrorMessage(error, status) {
4004
4189
  return `Seedance task ${status}`;
4005
4190
  }
4006
4191
  async function generateSeedanceVideo(req, ctx) {
4007
- const key = arkKey(ctx);
4008
4192
  const modelId = ctx.model.id;
4009
- const duration = req.durationSeconds ?? 5;
4193
+ const taskType = req.taskType;
4194
+ const hasVideo = Boolean(req.sourceVideo) || (req.referenceVideos?.length ?? 0) > 0;
4195
+ if ((taskType === "edit" || taskType === "extend") && !hasVideo) {
4196
+ throw new ModelKitError({
4197
+ code: "missing_input",
4198
+ message: `${ctx.model.id} ${taskType} task needs a source or reference video`,
4199
+ provider: "ark",
4200
+ model: ctx.model.id,
4201
+ retryable: false
4202
+ });
4203
+ }
4204
+ const key = arkKey(ctx);
4205
+ const requestedDuration = req.durationSeconds ?? 5;
4206
+ let duration = requestedDuration;
4207
+ if (taskType === "edit") duration = -1;
4010
4208
  const resolution = req.resolution ?? "720p";
4011
4209
  const content = [{ type: "text", text: req.prompt }];
4012
4210
  if (req.firstFrame) {
@@ -4058,7 +4256,10 @@ async function generateSeedanceVideo(req, ctx) {
4058
4256
  duration,
4059
4257
  resolution
4060
4258
  };
4061
- if (!hasFrameAnchor && req.aspectRatio !== void 0) body.ratio = req.aspectRatio;
4259
+ if (taskType === "edit" || taskType === "extend") body.ratio = "adaptive";
4260
+ else if (!hasFrameAnchor && req.aspectRatio !== void 0) body.ratio = req.aspectRatio;
4261
+ if (taskType !== void 0 && ctx.model.id === "seedance-2.5")
4262
+ body.omni_reference_task_type = taskType;
4062
4263
  if (req.generateAudio !== void 0) body.generate_audio = req.generateAudio;
4063
4264
  if (req.seed !== void 0) body.seed = req.seed;
4064
4265
  if (req.watermark !== void 0) body.watermark = req.watermark;
@@ -4078,7 +4279,7 @@ async function generateSeedanceVideo(req, ctx) {
4078
4279
  }, retryOptsFor(ctx));
4079
4280
  if (!submit.id) throwArkError(void 0, "Seedance task create returned no id", modelId);
4080
4281
  const jobId = submit.id;
4081
- const usage2 = seedanceUsage(ctx, req, duration);
4282
+ const usage2 = seedanceUsage(ctx, req, taskType === "edit" ? requestedDuration : duration);
4082
4283
  const fetchStatus = async () => {
4083
4284
  const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}${SUBMIT_PATH}/${jobId}`, {
4084
4285
  headers: { Authorization: `Bearer ${key}` }
@@ -4125,6 +4326,10 @@ async function generateSeedanceVideo(req, ctx) {
4125
4326
  "Seedance task succeeded but returned no video_url",
4126
4327
  modelId
4127
4328
  );
4329
+ if (polled.duration !== void 0 && polled.duration > 0) {
4330
+ usage2.quantity = polled.duration;
4331
+ usage2.durationSeconds = polled.duration;
4332
+ }
4128
4333
  const tokens = polled.usage;
4129
4334
  if (tokens?.total_tokens !== void 0 && tokens.completion_tokens !== void 0) {
4130
4335
  usage2.inputTokens = tokens.total_tokens - tokens.completion_tokens;
@@ -5180,7 +5385,7 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
5180
5385
  const apiKey = googleKey(ctx);
5181
5386
  const modelId = ctx.model.id;
5182
5387
  const providerModelId = ctx.model.providerModelId;
5183
- const duration = req.durationSeconds ?? 8;
5388
+ const duration = req.durationSeconds ?? 10;
5184
5389
  const images = req.referenceImages ?? [];
5185
5390
  const videos = req.referenceVideos ?? [];
5186
5391
  const task = req.sourceVideo ? "edit" : req.firstFrame ? "image_to_video" : images.length > 0 || videos.length > 0 ? "reference_to_video" : "text_to_video";
@@ -7447,6 +7652,7 @@ export {
7447
7652
  generateVideo,
7448
7653
  googleGenaiAdapter,
7449
7654
  googleImageAdapter,
7655
+ hasAwsCredentials,
7450
7656
  higgsfieldAdapter,
7451
7657
  isListed,
7452
7658
  isListedOn,