@shop-os/modelkit 0.4.5 → 0.4.7
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 +16 -0
- package/README.md +5 -1
- package/dist/catalog.cjs +1 -0
- package/dist/catalog.cjs.map +1 -1
- package/dist/catalog.d.cts +10 -1
- package/dist/catalog.d.ts +10 -1
- package/dist/catalog.js +1 -0
- package/dist/catalog.js.map +1 -1
- package/dist/index.cjs +210 -121
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -1
- package/dist/index.d.ts +18 -1
- package/dist/index.js +209 -121
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -52,6 +52,7 @@ __export(index_exports, {
|
|
|
52
52
|
SurfaceSchema: () => SurfaceSchema,
|
|
53
53
|
VIDEO_INPUT_SPEC_KEYS: () => VIDEO_INPUT_SPEC_KEYS,
|
|
54
54
|
VIDEO_TOOL_MODELS: () => VIDEO_TOOL_MODELS,
|
|
55
|
+
VideoResolutionSchema: () => VideoResolutionSchema,
|
|
55
56
|
adapterServesType: () => adapterServesType,
|
|
56
57
|
aiSdkTextAdapter: () => aiSdkTextAdapter,
|
|
57
58
|
arkAdapter: () => arkAdapter,
|
|
@@ -3770,6 +3771,11 @@ var arkAdapter = {
|
|
|
3770
3771
|
async generateVideo(req, ctx) {
|
|
3771
3772
|
throwIfAborted(ctx.signal);
|
|
3772
3773
|
return generateSeedanceVideo(req, ctx);
|
|
3774
|
+
},
|
|
3775
|
+
resumeVideo(req, jobId, ctx) {
|
|
3776
|
+
throwIfAborted(ctx.signal);
|
|
3777
|
+
const key = arkKey(ctx);
|
|
3778
|
+
return seedanceJob(ctx, key, jobId, seedanceUsage(ctx, req, seedanceInitialDuration(req)));
|
|
3773
3779
|
}
|
|
3774
3780
|
};
|
|
3775
3781
|
function arkKey(ctx) {
|
|
@@ -3927,17 +3933,22 @@ var SeedanceResponseSchema = import_zod7.z.object({
|
|
|
3927
3933
|
error: import_zod7.z.union([import_zod7.z.string(), import_zod7.z.object({ message: import_zod7.z.string().optional() })]).optional()
|
|
3928
3934
|
});
|
|
3929
3935
|
var SeedanceErrorMessageSchema = import_zod7.z.object({ message: import_zod7.z.string().optional() });
|
|
3936
|
+
function seedanceResolution(req) {
|
|
3937
|
+
return req.resolution ?? "720p";
|
|
3938
|
+
}
|
|
3930
3939
|
function seedanceUsage(ctx, req, duration) {
|
|
3931
|
-
|
|
3940
|
+
return {
|
|
3932
3941
|
model: ctx.model.id,
|
|
3933
3942
|
provider: "ark",
|
|
3934
3943
|
modality: "VIDEO",
|
|
3935
3944
|
unit: "seconds",
|
|
3936
3945
|
quantity: duration,
|
|
3937
|
-
durationSeconds: duration
|
|
3946
|
+
durationSeconds: duration,
|
|
3947
|
+
resolution: seedanceResolution(req)
|
|
3938
3948
|
};
|
|
3939
|
-
|
|
3940
|
-
|
|
3949
|
+
}
|
|
3950
|
+
function seedanceInitialDuration(req) {
|
|
3951
|
+
return req.durationSeconds ?? 5;
|
|
3941
3952
|
}
|
|
3942
3953
|
function seedanceErrorMessage(error, status) {
|
|
3943
3954
|
const asString = import_zod7.z.string().safeParse(error);
|
|
@@ -3946,6 +3957,82 @@ function seedanceErrorMessage(error, status) {
|
|
|
3946
3957
|
if (asObject.success && asObject.data.message !== void 0) return asObject.data.message;
|
|
3947
3958
|
return `Seedance task ${status}`;
|
|
3948
3959
|
}
|
|
3960
|
+
function seedanceJob(ctx, key, jobId, usage2) {
|
|
3961
|
+
const modelId = ctx.model.id;
|
|
3962
|
+
const fetchStatus = async () => {
|
|
3963
|
+
const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}${SUBMIT_PATH}/${jobId}`, {
|
|
3964
|
+
headers: { Authorization: `Bearer ${key}` }
|
|
3965
|
+
});
|
|
3966
|
+
if (!res.ok) {
|
|
3967
|
+
if (ctx.call.maxRetries !== 0 && (res.status === 429 || res.status >= 500))
|
|
3968
|
+
return void 0;
|
|
3969
|
+
const text2 = await res.text().catch(() => "");
|
|
3970
|
+
throwArkError(res.status, text2, modelId);
|
|
3971
|
+
}
|
|
3972
|
+
const parsed = SeedanceResponseSchema.safeParse(await res.json());
|
|
3973
|
+
if (!parsed.success) return {};
|
|
3974
|
+
return parsed.data;
|
|
3975
|
+
};
|
|
3976
|
+
return {
|
|
3977
|
+
jobId,
|
|
3978
|
+
async poll() {
|
|
3979
|
+
const polled = await fetchStatus();
|
|
3980
|
+
if (!polled) return { status: "running" };
|
|
3981
|
+
const status = (polled.status ?? "queued").toLowerCase();
|
|
3982
|
+
if (status === "succeeded") return { status: "succeeded", raw: polled };
|
|
3983
|
+
if (status === "failed" || status === "expired" || status === "cancelled") {
|
|
3984
|
+
return { status: "failed", raw: polled };
|
|
3985
|
+
}
|
|
3986
|
+
if (status === "queued" || status === "pending")
|
|
3987
|
+
return { status: "pending", raw: polled };
|
|
3988
|
+
return { status: "running", raw: polled };
|
|
3989
|
+
},
|
|
3990
|
+
async result(opts) {
|
|
3991
|
+
const optSignal = opts?.signal ?? ctx.signal;
|
|
3992
|
+
const pollOpts = {
|
|
3993
|
+
intervalMs: opts?.pollIntervalMs ?? SEEDANCE_POLL_INTERVAL_MS,
|
|
3994
|
+
timeoutMs: opts?.timeoutMs ?? RESULT_TIMEOUT_MS
|
|
3995
|
+
};
|
|
3996
|
+
if (optSignal !== void 0) pollOpts.signal = optSignal;
|
|
3997
|
+
return pollUntil(async () => {
|
|
3998
|
+
const polled = await fetchStatus();
|
|
3999
|
+
if (!polled) return void 0;
|
|
4000
|
+
const status = (polled.status ?? "queued").toLowerCase();
|
|
4001
|
+
if (status === "succeeded") {
|
|
4002
|
+
const url = polled.content?.video_url;
|
|
4003
|
+
if (!url)
|
|
4004
|
+
throwArkError(
|
|
4005
|
+
void 0,
|
|
4006
|
+
"Seedance task succeeded but returned no video_url",
|
|
4007
|
+
modelId
|
|
4008
|
+
);
|
|
4009
|
+
if (polled.duration !== void 0 && polled.duration > 0) {
|
|
4010
|
+
usage2.quantity = polled.duration;
|
|
4011
|
+
usage2.durationSeconds = polled.duration;
|
|
4012
|
+
}
|
|
4013
|
+
const rendered = VideoResolutionSchema.safeParse(
|
|
4014
|
+
polled.resolution?.toLowerCase()
|
|
4015
|
+
);
|
|
4016
|
+
if (rendered.success) usage2.resolution = rendered.data;
|
|
4017
|
+
const tokens = polled.usage;
|
|
4018
|
+
if (tokens?.total_tokens !== void 0 && tokens.completion_tokens !== void 0) {
|
|
4019
|
+
usage2.inputTokens = tokens.total_tokens - tokens.completion_tokens;
|
|
4020
|
+
usage2.outputTokens = tokens.completion_tokens;
|
|
4021
|
+
}
|
|
4022
|
+
return {
|
|
4023
|
+
video: { url, expiresAt: new Date(Date.now() + VIDEO_URL_TTL_MS) },
|
|
4024
|
+
usage: usage2,
|
|
4025
|
+
raw: polled
|
|
4026
|
+
};
|
|
4027
|
+
}
|
|
4028
|
+
if (status === "failed" || status === "expired" || status === "cancelled") {
|
|
4029
|
+
throwArkError(void 0, seedanceErrorMessage(polled.error, status), modelId);
|
|
4030
|
+
}
|
|
4031
|
+
return void 0;
|
|
4032
|
+
}, pollOpts);
|
|
4033
|
+
}
|
|
4034
|
+
};
|
|
4035
|
+
}
|
|
3949
4036
|
async function generateSeedanceVideo(req, ctx) {
|
|
3950
4037
|
const modelId = ctx.model.id;
|
|
3951
4038
|
const taskType = req.taskType;
|
|
@@ -3960,10 +4047,10 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
3960
4047
|
});
|
|
3961
4048
|
}
|
|
3962
4049
|
const key = arkKey(ctx);
|
|
3963
|
-
const requestedDuration = req
|
|
4050
|
+
const requestedDuration = seedanceInitialDuration(req);
|
|
3964
4051
|
let duration = requestedDuration;
|
|
3965
4052
|
if (taskType === "edit") duration = -1;
|
|
3966
|
-
const resolution = req
|
|
4053
|
+
const resolution = seedanceResolution(req);
|
|
3967
4054
|
const content = [{ type: "text", text: req.prompt }];
|
|
3968
4055
|
if (req.firstFrame) {
|
|
3969
4056
|
content.push({
|
|
@@ -4041,75 +4128,7 @@ async function generateSeedanceVideo(req, ctx) {
|
|
|
4041
4128
|
if (!submit.id) throwArkError(void 0, "Seedance task create returned no id", modelId);
|
|
4042
4129
|
const jobId = submit.id;
|
|
4043
4130
|
const usage2 = seedanceUsage(ctx, req, taskType === "edit" ? requestedDuration : duration);
|
|
4044
|
-
|
|
4045
|
-
const res = await arkFetch(ctx, `${arkBaseUrl(ctx)}${SUBMIT_PATH}/${jobId}`, {
|
|
4046
|
-
headers: { Authorization: `Bearer ${key}` }
|
|
4047
|
-
});
|
|
4048
|
-
if (!res.ok) {
|
|
4049
|
-
if (ctx.call.maxRetries !== 0 && (res.status === 429 || res.status >= 500))
|
|
4050
|
-
return void 0;
|
|
4051
|
-
const text2 = await res.text().catch(() => "");
|
|
4052
|
-
throwArkError(res.status, text2, modelId);
|
|
4053
|
-
}
|
|
4054
|
-
const parsed = SeedanceResponseSchema.safeParse(await res.json());
|
|
4055
|
-
if (!parsed.success) return {};
|
|
4056
|
-
return parsed.data;
|
|
4057
|
-
};
|
|
4058
|
-
return {
|
|
4059
|
-
jobId,
|
|
4060
|
-
async poll() {
|
|
4061
|
-
const polled = await fetchStatus();
|
|
4062
|
-
if (!polled) return { status: "running" };
|
|
4063
|
-
const status = (polled.status ?? "queued").toLowerCase();
|
|
4064
|
-
if (status === "succeeded") return { status: "succeeded", raw: polled };
|
|
4065
|
-
if (status === "failed" || status === "expired" || status === "cancelled") {
|
|
4066
|
-
return { status: "failed", raw: polled };
|
|
4067
|
-
}
|
|
4068
|
-
if (status === "queued" || status === "pending")
|
|
4069
|
-
return { status: "pending", raw: polled };
|
|
4070
|
-
return { status: "running", raw: polled };
|
|
4071
|
-
},
|
|
4072
|
-
async result(opts) {
|
|
4073
|
-
const optSignal = opts?.signal ?? ctx.signal;
|
|
4074
|
-
const pollOpts = {
|
|
4075
|
-
intervalMs: opts?.pollIntervalMs ?? SEEDANCE_POLL_INTERVAL_MS,
|
|
4076
|
-
timeoutMs: opts?.timeoutMs ?? RESULT_TIMEOUT_MS
|
|
4077
|
-
};
|
|
4078
|
-
if (optSignal !== void 0) pollOpts.signal = optSignal;
|
|
4079
|
-
return pollUntil(async () => {
|
|
4080
|
-
const polled = await fetchStatus();
|
|
4081
|
-
if (!polled) return void 0;
|
|
4082
|
-
const status = (polled.status ?? "queued").toLowerCase();
|
|
4083
|
-
if (status === "succeeded") {
|
|
4084
|
-
const url = polled.content?.video_url;
|
|
4085
|
-
if (!url)
|
|
4086
|
-
throwArkError(
|
|
4087
|
-
void 0,
|
|
4088
|
-
"Seedance task succeeded but returned no video_url",
|
|
4089
|
-
modelId
|
|
4090
|
-
);
|
|
4091
|
-
if (polled.duration !== void 0 && polled.duration > 0) {
|
|
4092
|
-
usage2.quantity = polled.duration;
|
|
4093
|
-
usage2.durationSeconds = polled.duration;
|
|
4094
|
-
}
|
|
4095
|
-
const tokens = polled.usage;
|
|
4096
|
-
if (tokens?.total_tokens !== void 0 && tokens.completion_tokens !== void 0) {
|
|
4097
|
-
usage2.inputTokens = tokens.total_tokens - tokens.completion_tokens;
|
|
4098
|
-
usage2.outputTokens = tokens.completion_tokens;
|
|
4099
|
-
}
|
|
4100
|
-
return {
|
|
4101
|
-
video: { url, expiresAt: new Date(Date.now() + VIDEO_URL_TTL_MS) },
|
|
4102
|
-
usage: usage2,
|
|
4103
|
-
raw: polled
|
|
4104
|
-
};
|
|
4105
|
-
}
|
|
4106
|
-
if (status === "failed" || status === "expired" || status === "cancelled") {
|
|
4107
|
-
throwArkError(void 0, seedanceErrorMessage(polled.error, status), modelId);
|
|
4108
|
-
}
|
|
4109
|
-
return void 0;
|
|
4110
|
-
}, pollOpts);
|
|
4111
|
-
}
|
|
4112
|
-
};
|
|
4131
|
+
return seedanceJob(ctx, key, jobId, usage2);
|
|
4113
4132
|
}
|
|
4114
4133
|
|
|
4115
4134
|
// src/adapters/fal.ts
|
|
@@ -4899,9 +4918,15 @@ function videoUsage(ctx, req, duration) {
|
|
|
4899
4918
|
quantity: duration,
|
|
4900
4919
|
durationSeconds: duration
|
|
4901
4920
|
};
|
|
4902
|
-
|
|
4921
|
+
const resolution = falVideoResolution(ctx.model.providerModelId, req);
|
|
4922
|
+
if (resolution !== void 0) event.resolution = resolution;
|
|
4903
4923
|
return event;
|
|
4904
4924
|
}
|
|
4925
|
+
function falVideoResolution(providerModelId, req) {
|
|
4926
|
+
if (isWan(providerModelId)) return wanResolution(req);
|
|
4927
|
+
if (isMinimax(providerModelId)) return minimaxResolution(req, minimaxFamily(providerModelId));
|
|
4928
|
+
return req.resolution;
|
|
4929
|
+
}
|
|
4905
4930
|
async function decodeImage(ctx, url, contentType) {
|
|
4906
4931
|
if (url.startsWith("data:")) {
|
|
4907
4932
|
const comma = url.indexOf(",");
|
|
@@ -5033,12 +5058,14 @@ function isFalVideoKnown(providerModelId) {
|
|
|
5033
5058
|
function minimaxFamily(providerModelId) {
|
|
5034
5059
|
return H3_MAX_MODEL_IDS.has(providerModelId.toLowerCase()) ? "h3-max" : "h3";
|
|
5035
5060
|
}
|
|
5061
|
+
function minimaxResolution(req, family) {
|
|
5062
|
+
return req.resolution ?? (family === "h3-max" ? "768p" : "2k");
|
|
5063
|
+
}
|
|
5036
5064
|
function minimaxBase(req, family) {
|
|
5037
|
-
const resolution = (family === "h3-max" ? req.resolution ?? "768p" : req.resolution ?? "2k").toUpperCase();
|
|
5038
5065
|
const input = {
|
|
5039
5066
|
prompt: req.prompt.trim(),
|
|
5040
5067
|
duration: req.durationSeconds ?? 5,
|
|
5041
|
-
resolution,
|
|
5068
|
+
resolution: minimaxResolution(req, family).toUpperCase(),
|
|
5042
5069
|
prompt_expansion_mode: req.promptExpansion ?? "balanced"
|
|
5043
5070
|
};
|
|
5044
5071
|
if (req.safetyChecker !== void 0) input.enable_safety_checker = req.safetyChecker;
|
|
@@ -5049,11 +5076,14 @@ var WAN_MODEL_IDS = /* @__PURE__ */ new Set(["alibaba/wan-3.0"]);
|
|
|
5049
5076
|
function isWan(providerModelId) {
|
|
5050
5077
|
return WAN_MODEL_IDS.has(providerModelId.toLowerCase());
|
|
5051
5078
|
}
|
|
5079
|
+
function wanResolution(req) {
|
|
5080
|
+
return req.resolution ?? "1080p";
|
|
5081
|
+
}
|
|
5052
5082
|
function wanVideo(req, family) {
|
|
5053
5083
|
const input = {
|
|
5054
5084
|
prompt: req.prompt.trim(),
|
|
5055
5085
|
duration: req.durationSeconds ?? 5,
|
|
5056
|
-
resolution: req
|
|
5086
|
+
resolution: wanResolution(req),
|
|
5057
5087
|
aspect_ratio: req.aspectRatio ?? "adaptive",
|
|
5058
5088
|
audio: req.generateAudio ?? true
|
|
5059
5089
|
};
|
|
@@ -5652,7 +5682,7 @@ async function downloadVideo(ctx, url, apiKey, signal) {
|
|
|
5652
5682
|
mime: res.headers.get("content-type")?.split(";")[0]?.trim() || "video/mp4"
|
|
5653
5683
|
};
|
|
5654
5684
|
}
|
|
5655
|
-
function videoUsage2(ctx,
|
|
5685
|
+
function videoUsage2(ctx, duration, resolution) {
|
|
5656
5686
|
const event = {
|
|
5657
5687
|
model: ctx.model.id,
|
|
5658
5688
|
provider: "google-genai",
|
|
@@ -5661,7 +5691,7 @@ function videoUsage2(ctx, req, duration) {
|
|
|
5661
5691
|
quantity: duration,
|
|
5662
5692
|
durationSeconds: duration
|
|
5663
5693
|
};
|
|
5664
|
-
if (
|
|
5694
|
+
if (resolution !== void 0) event.resolution = resolution;
|
|
5665
5695
|
return event;
|
|
5666
5696
|
}
|
|
5667
5697
|
async function generateVeoVideo(req, ctx, createGenAIClient) {
|
|
@@ -5755,7 +5785,7 @@ async function generateVeoVideo(req, ctx, createGenAIClient) {
|
|
|
5755
5785
|
}
|
|
5756
5786
|
};
|
|
5757
5787
|
const jobId = operation.name ?? crypto.randomUUID();
|
|
5758
|
-
const usage2 = videoUsage2(ctx,
|
|
5788
|
+
const usage2 = videoUsage2(ctx, duration, req.resolution ?? "720p");
|
|
5759
5789
|
return {
|
|
5760
5790
|
jobId,
|
|
5761
5791
|
async poll() {
|
|
@@ -5879,10 +5909,8 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
5879
5909
|
if (req.sourceVideo === void 0 && !extend && req.aspectRatio !== void 0 && req.aspectRatio !== "adaptive") {
|
|
5880
5910
|
responseFormat.aspect_ratio = toOmniAspect(req.aspectRatio);
|
|
5881
5911
|
}
|
|
5882
|
-
|
|
5883
|
-
|
|
5884
|
-
if (omniResolution !== void 0) responseFormat.resolution = omniResolution;
|
|
5885
|
-
}
|
|
5912
|
+
const omniResolution = isOmniV1 ? void 0 : toOmniResolution(req.resolution);
|
|
5913
|
+
if (omniResolution !== void 0) responseFormat.resolution = omniResolution;
|
|
5886
5914
|
if (req.durationSeconds !== void 0) responseFormat.duration = `${req.durationSeconds}s`;
|
|
5887
5915
|
const client2 = createGenAIClient({
|
|
5888
5916
|
apiKey,
|
|
@@ -6000,7 +6028,7 @@ async function generateOmniVideo(req, ctx, createGenAIClient) {
|
|
|
6000
6028
|
if (!(extend && !chained)) await cleanupUploads();
|
|
6001
6029
|
}
|
|
6002
6030
|
const jobId = interaction.id ?? crypto.randomUUID();
|
|
6003
|
-
const usage2 = videoUsage2(ctx,
|
|
6031
|
+
const usage2 = videoUsage2(ctx, duration, omniResolution ?? "720p");
|
|
6004
6032
|
const getInteraction = async () => {
|
|
6005
6033
|
try {
|
|
6006
6034
|
const getParams = { stream: false };
|
|
@@ -7582,7 +7610,8 @@ function videoUsage4(ctx, req) {
|
|
|
7582
7610
|
unit: "compute_seconds",
|
|
7583
7611
|
quantity: 0
|
|
7584
7612
|
};
|
|
7585
|
-
|
|
7613
|
+
const resolution = replicateVideoResolution(ctx.model.providerModelId, req);
|
|
7614
|
+
if (resolution !== void 0) event.resolution = resolution;
|
|
7586
7615
|
if (req.durationSeconds !== void 0) event.durationSeconds = req.durationSeconds;
|
|
7587
7616
|
return event;
|
|
7588
7617
|
}
|
|
@@ -7819,7 +7848,7 @@ function klingInput(req) {
|
|
|
7819
7848
|
const input = {
|
|
7820
7849
|
prompt: req.prompt,
|
|
7821
7850
|
duration: req.durationSeconds ?? 10,
|
|
7822
|
-
mode: req.mode
|
|
7851
|
+
mode: klingTier(req).mode,
|
|
7823
7852
|
generate_audio: req.generateAudio ?? false
|
|
7824
7853
|
};
|
|
7825
7854
|
const startImage = images[0];
|
|
@@ -7833,17 +7862,25 @@ function klingInput(req) {
|
|
|
7833
7862
|
if (req.negativePrompt !== void 0) input.negative_prompt = req.negativePrompt;
|
|
7834
7863
|
return input;
|
|
7835
7864
|
}
|
|
7836
|
-
function
|
|
7837
|
-
|
|
7838
|
-
if (
|
|
7839
|
-
if (
|
|
7840
|
-
return req.
|
|
7865
|
+
function replicateVideoResolution(providerModelId, req) {
|
|
7866
|
+
const kind = videoKind(providerModelId);
|
|
7867
|
+
if (kind === "kling" || kind === "kling-omni") return klingTier(req).resolution;
|
|
7868
|
+
if (kind === "hailuo") return hailuoResolution(req);
|
|
7869
|
+
return req.resolution;
|
|
7870
|
+
}
|
|
7871
|
+
var KLING_TIERS = [
|
|
7872
|
+
{ mode: "standard", resolution: "720p" },
|
|
7873
|
+
{ mode: "pro", resolution: "1080p" },
|
|
7874
|
+
{ mode: "4k", resolution: "4k" }
|
|
7875
|
+
];
|
|
7876
|
+
function klingTier(req) {
|
|
7877
|
+
return KLING_TIERS.find((tier) => tier.resolution === req.resolution) ?? KLING_TIERS.find((tier) => tier.mode === req.mode) ?? KLING_TIERS[0];
|
|
7841
7878
|
}
|
|
7842
7879
|
function klingOmniInput(req) {
|
|
7843
7880
|
const input = {
|
|
7844
7881
|
prompt: req.prompt,
|
|
7845
7882
|
duration: req.durationSeconds ?? 10,
|
|
7846
|
-
mode:
|
|
7883
|
+
mode: klingTier(req).mode,
|
|
7847
7884
|
generate_audio: req.generateAudio ?? false
|
|
7848
7885
|
};
|
|
7849
7886
|
const start = req.firstFrame ?? req.lastFrame;
|
|
@@ -7857,11 +7894,14 @@ function klingOmniInput(req) {
|
|
|
7857
7894
|
if (refs.length > 0) input.reference_images = refs;
|
|
7858
7895
|
return input;
|
|
7859
7896
|
}
|
|
7897
|
+
function hailuoResolution(req) {
|
|
7898
|
+
return req.resolution ?? "768p";
|
|
7899
|
+
}
|
|
7860
7900
|
function hailuoInput(req) {
|
|
7861
7901
|
const input = {
|
|
7862
7902
|
prompt: req.prompt,
|
|
7863
7903
|
duration: req.durationSeconds ?? 6,
|
|
7864
|
-
resolution: req
|
|
7904
|
+
resolution: hailuoResolution(req),
|
|
7865
7905
|
prompt_optimizer: true
|
|
7866
7906
|
};
|
|
7867
7907
|
if (req.firstFrame) input.first_frame_image = refToUrl(req.firstFrame);
|
|
@@ -9689,6 +9729,33 @@ function createModelKit(config, adapters) {
|
|
|
9689
9729
|
result: () => done
|
|
9690
9730
|
};
|
|
9691
9731
|
}
|
|
9732
|
+
function wrapVideoJob(model, job, warnings, startedAt) {
|
|
9733
|
+
const result = job.result.bind(job);
|
|
9734
|
+
let settled;
|
|
9735
|
+
return {
|
|
9736
|
+
...job,
|
|
9737
|
+
warnings,
|
|
9738
|
+
result(opts) {
|
|
9739
|
+
if (settled) return settled;
|
|
9740
|
+
const pending = result(opts).then(
|
|
9741
|
+
async (out) => {
|
|
9742
|
+
const usage2 = timed(
|
|
9743
|
+
{ ...out.usage, model: model.id, unit: model.usage.unit },
|
|
9744
|
+
startedAt
|
|
9745
|
+
);
|
|
9746
|
+
await emit(usage2);
|
|
9747
|
+
return { ...out, usage: usage2 };
|
|
9748
|
+
},
|
|
9749
|
+
(cause) => {
|
|
9750
|
+
settled = void 0;
|
|
9751
|
+
throw cause;
|
|
9752
|
+
}
|
|
9753
|
+
);
|
|
9754
|
+
settled = pending;
|
|
9755
|
+
return pending;
|
|
9756
|
+
}
|
|
9757
|
+
};
|
|
9758
|
+
}
|
|
9692
9759
|
return {
|
|
9693
9760
|
catalog,
|
|
9694
9761
|
describe: (id) => catalog.require(id),
|
|
@@ -9773,31 +9840,52 @@ function createModelKit(config, adapters) {
|
|
|
9773
9840
|
});
|
|
9774
9841
|
const startedAt = Date.now();
|
|
9775
9842
|
const job = await adapter.generateVideo(request, ctx);
|
|
9776
|
-
|
|
9777
|
-
|
|
9778
|
-
|
|
9779
|
-
|
|
9780
|
-
|
|
9781
|
-
|
|
9782
|
-
|
|
9783
|
-
|
|
9784
|
-
|
|
9785
|
-
|
|
9786
|
-
|
|
9787
|
-
|
|
9788
|
-
|
|
9789
|
-
|
|
9790
|
-
|
|
9791
|
-
|
|
9792
|
-
|
|
9793
|
-
|
|
9794
|
-
|
|
9795
|
-
|
|
9796
|
-
|
|
9797
|
-
|
|
9798
|
-
|
|
9799
|
-
}
|
|
9800
|
-
}
|
|
9843
|
+
return wrapVideoJob(model, job, warnings, startedAt);
|
|
9844
|
+
},
|
|
9845
|
+
async resumeVideo(req, jobId, call = {}) {
|
|
9846
|
+
mediaRetryOptions(call);
|
|
9847
|
+
if (!jobId) {
|
|
9848
|
+
throw new ModelKitError({
|
|
9849
|
+
code: "missing_input",
|
|
9850
|
+
message: "resumeVideo needs a jobId",
|
|
9851
|
+
retryable: false
|
|
9852
|
+
});
|
|
9853
|
+
}
|
|
9854
|
+
if (!isCatalogId(req.model)) {
|
|
9855
|
+
throw new ModelKitError({
|
|
9856
|
+
code: "unsupported_option",
|
|
9857
|
+
message: "resumeVideo needs a catalog model id"
|
|
9858
|
+
});
|
|
9859
|
+
}
|
|
9860
|
+
const model = catalog.require(req.model);
|
|
9861
|
+
if (model.type !== "video")
|
|
9862
|
+
throw new ModelKitError({
|
|
9863
|
+
code: "unsupported_option",
|
|
9864
|
+
message: `${model.id} is not a video model`,
|
|
9865
|
+
model: model.id
|
|
9866
|
+
});
|
|
9867
|
+
const { request: input, warnings: inputWarnings } = videoRequestOf({
|
|
9868
|
+
...req,
|
|
9869
|
+
model: req.model
|
|
9870
|
+
});
|
|
9871
|
+
const { request, warnings } = resolveVideoOptions(
|
|
9872
|
+
model,
|
|
9873
|
+
input,
|
|
9874
|
+
call.onUnsupported ?? "error"
|
|
9875
|
+
);
|
|
9876
|
+
warnings.push(...inputWarnings);
|
|
9877
|
+
logCoercions(logger, model.id, warnings);
|
|
9878
|
+
const signal = combineSignals(req.abortSignal, call.signal);
|
|
9879
|
+
const { adapter, ctx } = context(model, signal ? { ...call, signal } : call, warnings);
|
|
9880
|
+
if (!adapter.resumeVideo)
|
|
9881
|
+
throw new ModelKitError({
|
|
9882
|
+
code: "unsupported_option",
|
|
9883
|
+
message: `${adapter.id} cannot resume a video job`,
|
|
9884
|
+
model: model.id
|
|
9885
|
+
});
|
|
9886
|
+
const startedAt = Date.now();
|
|
9887
|
+
const job = adapter.resumeVideo(request, jobId, ctx);
|
|
9888
|
+
return wrapVideoJob(model, { ...job, jobId }, warnings, startedAt);
|
|
9801
9889
|
},
|
|
9802
9890
|
async generateAudio(req, call = {}) {
|
|
9803
9891
|
mediaRetryOptions(call);
|
|
@@ -10042,6 +10130,7 @@ var describe = (modelId) => createDefaultModelKit().describe(modelId);
|
|
|
10042
10130
|
SurfaceSchema,
|
|
10043
10131
|
VIDEO_INPUT_SPEC_KEYS,
|
|
10044
10132
|
VIDEO_TOOL_MODELS,
|
|
10133
|
+
VideoResolutionSchema,
|
|
10045
10134
|
adapterServesType,
|
|
10046
10135
|
aiSdkTextAdapter,
|
|
10047
10136
|
arkAdapter,
|