@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/CHANGELOG.md +20 -0
- package/README.md +61 -0
- package/dist/catalog.cjs +26 -4
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.cts +28 -5
- package/dist/catalog.d.ts +28 -5
- package/dist/catalog.js +26 -4
- package/dist/catalog.js.map +1 -1
- package/dist/index.cjs +238 -31
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +34 -6
- package/dist/index.d.ts +34 -6
- package/dist/index.js +235 -29
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
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,
|
|
3060
|
-
|
|
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
|
-
|
|
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.
|
|
3094
|
-
|
|
3095
|
-
|
|
3096
|
-
|
|
3097
|
-
|
|
3098
|
-
|
|
3099
|
-
|
|
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
|
-
|
|
3183
|
-
|
|
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,
|
|
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
|
|
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
|
|
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
|
|
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 (
|
|
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 ??
|
|
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,
|