@mux/ai 0.7.4 → 0.7.6
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-Bavk1Y8-.d.ts → index-B0U9upb4.d.ts} +7 -3
- package/dist/{index-DZlygsvb.d.ts → index-Nxf6BaBO.d.ts} +1 -1
- package/dist/index.d.ts +5 -5
- package/dist/index.js +72 -22
- package/dist/index.js.map +1 -1
- package/dist/primitives/index.d.ts +2 -2
- package/dist/primitives/index.js +55 -10
- package/dist/primitives/index.js.map +1 -1
- package/dist/{types-BQVi_wnh.d.ts → types-BRbaGW3t.d.ts} +2 -0
- package/dist/workflows/index.d.ts +2 -2
- package/dist/workflows/index.js +71 -21
- package/dist/workflows/index.js.map +1 -1
- package/package.json +1 -1
package/dist/workflows/index.js
CHANGED
|
@@ -138,6 +138,10 @@ var EnvSchema = z.object({
|
|
|
138
138
|
),
|
|
139
139
|
MUX_SIGNING_KEY: optionalString("Mux signing key ID for signed playback URLs.", "Used to sign playback URLs"),
|
|
140
140
|
MUX_PRIVATE_KEY: optionalString("Mux signing private key for signed playback URLs.", "Used to sign playback URLs"),
|
|
141
|
+
MUX_IMAGE_URL_OVERRIDE: optionalString(
|
|
142
|
+
"Override for Mux image base URL (defaults to https://image.mux.com).",
|
|
143
|
+
"Mux image URL override"
|
|
144
|
+
),
|
|
141
145
|
// Test-only helpers (used by this repo's integration tests)
|
|
142
146
|
MUX_TEST_ASSET_ID: optionalString("Mux asset ID used by integration tests.", "Mux test asset id"),
|
|
143
147
|
MUX_TEST_ASSET_ID_CHAPTERS: optionalString("Mux asset ID used by integration tests for chapters.", "Mux test asset id for chapters"),
|
|
@@ -424,12 +428,13 @@ function readString(record, key) {
|
|
|
424
428
|
function resolveDirectMuxCredentials(record) {
|
|
425
429
|
const tokenId = readString(record, "muxTokenId");
|
|
426
430
|
const tokenSecret = readString(record, "muxTokenSecret");
|
|
431
|
+
const authorizationToken = readString(record, "muxAuthorizationToken");
|
|
427
432
|
const signingKey = readString(record, "muxSigningKey");
|
|
428
433
|
const privateKey = readString(record, "muxPrivateKey");
|
|
429
|
-
if (!tokenId && !tokenSecret && !signingKey && !privateKey) {
|
|
434
|
+
if (!tokenId && !tokenSecret && !authorizationToken && !signingKey && !privateKey) {
|
|
430
435
|
return void 0;
|
|
431
436
|
}
|
|
432
|
-
if (!tokenId || !tokenSecret) {
|
|
437
|
+
if ((!tokenId || !tokenSecret) && !authorizationToken) {
|
|
433
438
|
throw new Error(
|
|
434
439
|
"Both muxTokenId and muxTokenSecret are required when passing direct Mux workflow credentials."
|
|
435
440
|
);
|
|
@@ -437,6 +442,7 @@ function resolveDirectMuxCredentials(record) {
|
|
|
437
442
|
return {
|
|
438
443
|
tokenId,
|
|
439
444
|
tokenSecret,
|
|
445
|
+
authorizationToken,
|
|
440
446
|
signingKey,
|
|
441
447
|
privateKey
|
|
442
448
|
};
|
|
@@ -447,7 +453,8 @@ function createWorkflowMuxClient(options) {
|
|
|
447
453
|
const { default: MuxClient } = await import("@mux/mux-node");
|
|
448
454
|
return new MuxClient({
|
|
449
455
|
tokenId: options.tokenId,
|
|
450
|
-
tokenSecret: options.tokenSecret
|
|
456
|
+
tokenSecret: options.tokenSecret,
|
|
457
|
+
authorizationToken: options.authorizationToken
|
|
451
458
|
});
|
|
452
459
|
},
|
|
453
460
|
getSigningKey() {
|
|
@@ -832,6 +839,44 @@ async function withRetry(fn, {
|
|
|
832
839
|
throw lastError || new Error("Retry failed with unknown error");
|
|
833
840
|
}
|
|
834
841
|
|
|
842
|
+
// src/lib/mux-image-url.ts
|
|
843
|
+
var DEFAULT_MUX_IMAGE_ORIGIN = "https://image.mux.com";
|
|
844
|
+
function normalizeMuxImageOrigin(value) {
|
|
845
|
+
const trimmed = value.trim();
|
|
846
|
+
const candidate = trimmed.includes("://") ? trimmed : `https://${trimmed}`;
|
|
847
|
+
let parsed;
|
|
848
|
+
try {
|
|
849
|
+
parsed = new URL(candidate);
|
|
850
|
+
} catch {
|
|
851
|
+
throw new Error(
|
|
852
|
+
`Invalid MUX_IMAGE_URL_OVERRIDE. Provide a hostname like "image.example.mux.com" (or a URL origin such as "https://image.example.mux.com").`
|
|
853
|
+
);
|
|
854
|
+
}
|
|
855
|
+
if (parsed.username || parsed.password || parsed.search || parsed.hash || parsed.pathname && parsed.pathname !== "/") {
|
|
856
|
+
throw new Error(
|
|
857
|
+
"Invalid MUX_IMAGE_URL_OVERRIDE. Only a hostname/origin is allowed (no credentials, query params, hash fragments, or path)."
|
|
858
|
+
);
|
|
859
|
+
}
|
|
860
|
+
return parsed.origin;
|
|
861
|
+
}
|
|
862
|
+
function getMuxImageOrigin() {
|
|
863
|
+
const override = env_default.MUX_IMAGE_URL_OVERRIDE;
|
|
864
|
+
if (!override) {
|
|
865
|
+
return DEFAULT_MUX_IMAGE_ORIGIN;
|
|
866
|
+
}
|
|
867
|
+
return normalizeMuxImageOrigin(override);
|
|
868
|
+
}
|
|
869
|
+
function getMuxImageBaseUrl(playbackId, assetType) {
|
|
870
|
+
const origin = getMuxImageOrigin();
|
|
871
|
+
return `${origin}/${playbackId}/${assetType}.png`;
|
|
872
|
+
}
|
|
873
|
+
function getMuxStoryboardBaseUrl(playbackId) {
|
|
874
|
+
return getMuxImageBaseUrl(playbackId, "storyboard");
|
|
875
|
+
}
|
|
876
|
+
function getMuxThumbnailBaseUrl(playbackId) {
|
|
877
|
+
return getMuxImageBaseUrl(playbackId, "thumbnail");
|
|
878
|
+
}
|
|
879
|
+
|
|
835
880
|
// src/lib/url-signing.ts
|
|
836
881
|
async function createSigningClient(context) {
|
|
837
882
|
const { default: MuxClient } = await import("@mux/mux-node");
|
|
@@ -856,9 +901,9 @@ async function signPlaybackId(playbackId, context, type = "video", params) {
|
|
|
856
901
|
params: stringParams
|
|
857
902
|
});
|
|
858
903
|
}
|
|
859
|
-
async function signUrl(url, playbackId,
|
|
904
|
+
async function signUrl(url, playbackId, type = "video", params, credentials) {
|
|
860
905
|
"use step";
|
|
861
|
-
const resolvedContext =
|
|
906
|
+
const resolvedContext = await resolveMuxSigningContext(credentials);
|
|
862
907
|
if (!resolvedContext) {
|
|
863
908
|
throw new Error(
|
|
864
909
|
"Signed playback ID requires signing credentials. Provide muxSigningKey and muxPrivateKey via workflow credentials or set MUX_SIGNING_KEY and MUX_PRIVATE_KEY environment variables."
|
|
@@ -873,9 +918,9 @@ async function signUrl(url, playbackId, context, type = "video", params, credent
|
|
|
873
918
|
var DEFAULT_STORYBOARD_WIDTH = 640;
|
|
874
919
|
async function getStoryboardUrl(playbackId, width = DEFAULT_STORYBOARD_WIDTH, shouldSign = false, credentials) {
|
|
875
920
|
"use step";
|
|
876
|
-
const baseUrl =
|
|
921
|
+
const baseUrl = getMuxStoryboardBaseUrl(playbackId);
|
|
877
922
|
if (shouldSign) {
|
|
878
|
-
return signUrl(baseUrl, playbackId,
|
|
923
|
+
return signUrl(baseUrl, playbackId, "storyboard", { width }, credentials);
|
|
879
924
|
}
|
|
880
925
|
return `${baseUrl}?width=${width}`;
|
|
881
926
|
}
|
|
@@ -992,7 +1037,7 @@ async function buildTranscriptUrl(playbackId, trackId, shouldSign = false, crede
|
|
|
992
1037
|
"use step";
|
|
993
1038
|
const baseUrl = `https://stream.mux.com/${playbackId}/text/${trackId}.vtt`;
|
|
994
1039
|
if (shouldSign) {
|
|
995
|
-
return signUrl(baseUrl, playbackId,
|
|
1040
|
+
return signUrl(baseUrl, playbackId, "video", void 0, credentials);
|
|
996
1041
|
}
|
|
997
1042
|
return baseUrl;
|
|
998
1043
|
}
|
|
@@ -2082,10 +2127,10 @@ async function getThumbnailUrls(playbackId, duration, options = {}) {
|
|
|
2082
2127
|
}
|
|
2083
2128
|
timestamps = newTimestamps;
|
|
2084
2129
|
}
|
|
2085
|
-
const baseUrl =
|
|
2130
|
+
const baseUrl = getMuxThumbnailBaseUrl(playbackId);
|
|
2086
2131
|
const urlPromises = timestamps.map(async (time) => {
|
|
2087
2132
|
if (shouldSign) {
|
|
2088
|
-
return signUrl(baseUrl, playbackId,
|
|
2133
|
+
return signUrl(baseUrl, playbackId, "thumbnail", { time, width }, credentials);
|
|
2089
2134
|
}
|
|
2090
2135
|
return `${baseUrl}?time=${time}&width=${width}`;
|
|
2091
2136
|
});
|
|
@@ -2101,11 +2146,10 @@ var DEFAULT_PROVIDER2 = "openai";
|
|
|
2101
2146
|
var HIVE_ENDPOINT = "https://api.thehive.ai/api/v2/task/sync";
|
|
2102
2147
|
var HIVE_SEXUAL_CATEGORIES = [
|
|
2103
2148
|
"general_nsfw",
|
|
2104
|
-
"general_suggestive",
|
|
2105
2149
|
"yes_sexual_activity",
|
|
2106
|
-
"
|
|
2107
|
-
"
|
|
2108
|
-
"
|
|
2150
|
+
"yes_sex_toy",
|
|
2151
|
+
"yes_female_nudity",
|
|
2152
|
+
"yes_male_nudity"
|
|
2109
2153
|
];
|
|
2110
2154
|
var HIVE_VIOLENCE_CATEGORIES = [
|
|
2111
2155
|
"gun_in_hand",
|
|
@@ -2116,10 +2160,8 @@ var HIVE_VIOLENCE_CATEGORIES = [
|
|
|
2116
2160
|
"hanging",
|
|
2117
2161
|
"noose",
|
|
2118
2162
|
"human_corpse",
|
|
2119
|
-
"
|
|
2120
|
-
"
|
|
2121
|
-
"animal_abuse",
|
|
2122
|
-
"fights",
|
|
2163
|
+
"yes_emaciated_body",
|
|
2164
|
+
"yes_self_harm",
|
|
2123
2165
|
"garm_death_injury_or_military_conflict"
|
|
2124
2166
|
];
|
|
2125
2167
|
async function processConcurrently(items, processor, maxConcurrent = 5) {
|
|
@@ -2263,6 +2305,12 @@ function getHiveCategoryScores(classes, categoryNames) {
|
|
|
2263
2305
|
const scoreMap = Object.fromEntries(
|
|
2264
2306
|
classes.map((c) => [c.class, c.score])
|
|
2265
2307
|
);
|
|
2308
|
+
const missingCategories = categoryNames.filter((category) => !(category in scoreMap));
|
|
2309
|
+
if (missingCategories.length > 0) {
|
|
2310
|
+
console.warn(
|
|
2311
|
+
`Hive response missing expected categories: ${missingCategories.join(", ")}`
|
|
2312
|
+
);
|
|
2313
|
+
}
|
|
2266
2314
|
const scores = categoryNames.map((category) => scoreMap[category] || 0);
|
|
2267
2315
|
return Math.max(...scores, 0);
|
|
2268
2316
|
}
|
|
@@ -2356,11 +2404,11 @@ async function requestHiveModeration(imageUrls, maxConcurrent = 5, submissionMod
|
|
|
2356
2404
|
async function getThumbnailUrlsFromTimestamps(playbackId, timestampsMs, options) {
|
|
2357
2405
|
"use step";
|
|
2358
2406
|
const { width, shouldSign, credentials } = options;
|
|
2359
|
-
const baseUrl =
|
|
2407
|
+
const baseUrl = getMuxThumbnailBaseUrl(playbackId);
|
|
2360
2408
|
const urlPromises = timestampsMs.map(async (tsMs) => {
|
|
2361
2409
|
const time = Number((tsMs / 1e3).toFixed(2));
|
|
2362
2410
|
if (shouldSign) {
|
|
2363
|
-
return signUrl(baseUrl, playbackId,
|
|
2411
|
+
return signUrl(baseUrl, playbackId, "thumbnail", { time, width }, credentials);
|
|
2364
2412
|
}
|
|
2365
2413
|
return `${baseUrl}?time=${time}&width=${width}`;
|
|
2366
2414
|
});
|
|
@@ -3633,7 +3681,7 @@ async function translateAudio(assetId, toLanguageCode, options = {}) {
|
|
|
3633
3681
|
}
|
|
3634
3682
|
let audioUrl = `https://stream.mux.com/${playbackId}/audio.m4a`;
|
|
3635
3683
|
if (policy === "signed") {
|
|
3636
|
-
audioUrl = await signUrl(audioUrl, playbackId,
|
|
3684
|
+
audioUrl = await signUrl(audioUrl, playbackId, "video", void 0, credentials);
|
|
3637
3685
|
}
|
|
3638
3686
|
console.warn("\u{1F399}\uFE0F Fetching audio from Mux...");
|
|
3639
3687
|
let audioBuffer;
|
|
@@ -4013,6 +4061,8 @@ async function translateCaptions(assetId, fromLanguageCode, toLanguageCode, opti
|
|
|
4013
4061
|
};
|
|
4014
4062
|
}
|
|
4015
4063
|
export {
|
|
4064
|
+
HIVE_SEXUAL_CATEGORIES,
|
|
4065
|
+
HIVE_VIOLENCE_CATEGORIES,
|
|
4016
4066
|
SUMMARY_KEYWORD_LIMIT,
|
|
4017
4067
|
askQuestions,
|
|
4018
4068
|
burnedInCaptionsSchema,
|