vidspotai-shared 1.0.130 → 1.0.131
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/lib/globals/aiModels/enums.d.ts +2 -0
- package/lib/globals/aiModels/enums.d.ts.map +1 -1
- package/lib/globals/aiModels/enums.js +22 -1
- package/lib/globals/aiModels/providers/bytedance.d.ts.map +1 -1
- package/lib/globals/aiModels/providers/bytedance.js +4 -0
- package/lib/globals/aiModels/tierHelpers.d.ts +3 -1
- package/lib/globals/aiModels/tierHelpers.d.ts.map +1 -1
- package/lib/globals/aiModels/tierHelpers.js +7 -1
- package/lib/globals/aiModels/types.d.ts +7 -0
- package/lib/globals/aiModels/types.d.ts.map +1 -1
- package/lib/services/agent/planner/Planner.d.ts.map +1 -1
- package/lib/services/agent/planner/Planner.js +9 -0
- package/lib/services/agent/providerFallback/chains.d.ts.map +1 -1
- package/lib/services/agent/providerFallback/chains.js +5 -1
- package/lib/services/agent/tools/searchUserLibrary.tool.d.ts.map +1 -1
- package/lib/services/agent/tools/searchUserLibrary.tool.js +7 -1
- package/lib/services/aiGen/helpers.d.ts.map +1 -1
- package/lib/services/aiGen/helpers.js +5 -0
- package/lib/services/aiGen/providers/alibaba/alibaba.d.ts.map +1 -1
- package/lib/services/aiGen/providers/alibaba/alibaba.js +27 -0
- package/lib/services/aiGen/providers/bytedance/bytedance.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/bytedance/bytedance.service.js +6 -0
- package/lib/services/aiGen/providers/google/googleMusic.d.ts.map +1 -1
- package/lib/services/aiGen/providers/google/googleMusic.js +14 -1
- package/lib/services/aiGen/providers/runway/runway.service.d.ts +2 -2
- package/lib/services/aiGen/providers/runway/runway.service.d.ts.map +1 -1
- package/lib/services/aiGen/providers/runway/runway.service.js +81 -3
- package/lib/services/bullmq.service.d.ts +11 -0
- package/lib/services/bullmq.service.d.ts.map +1 -1
- package/lib/services/bullmq.service.js +79 -18
- package/lib/services/translation/index.d.ts +1 -1
- package/lib/services/translation/index.d.ts.map +1 -1
- package/lib/services/translation/index.js +2 -1
- package/lib/services/translation/outputLanguage.d.ts +9 -0
- package/lib/services/translation/outputLanguage.d.ts.map +1 -1
- package/lib/services/translation/outputLanguage.js +53 -1
- package/lib/services/translation/translation.service.d.ts +16 -0
- package/lib/services/translation/translation.service.d.ts.map +1 -1
- package/lib/services/translation/translation.service.js +47 -0
- package/lib/utils/errors.d.ts +7 -0
- package/lib/utils/errors.d.ts.map +1 -1
- package/lib/utils/errors.js +23 -0
- package/package.json +1 -1
|
@@ -133,6 +133,8 @@ export declare enum EMusicGenModels {
|
|
|
133
133
|
GOOGLE_LYRIA_3 = "google-lyria-3",
|
|
134
134
|
GOOGLE_LYRIA_3_PRO = "google-lyria-3-pro"
|
|
135
135
|
}
|
|
136
|
+
export declare const DEFAULT_MUSIC_MODEL = EMusicGenModels.GOOGLE_LYRIA_2;
|
|
137
|
+
export declare function resolveMusicModelKey(key: EMusicGenModels): EMusicGenModels;
|
|
136
138
|
export declare enum ETextGenModels {
|
|
137
139
|
OPENAI_GPT_5_5 = "openai-gpt-5.5",
|
|
138
140
|
OPENAI_GPT_5_4_MINI = "openai-gpt-5.4-mini",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"enums.d.ts","sourceRoot":"","sources":["../../../src/globals/aiModels/enums.ts"],"names":[],"mappings":"AAAA,oBAAY,eAAe;IACzB,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;IAC3B,aAAa,kBAAkB;IAC/B,aAAa,kBAAkB;IAC/B,WAAW,gBAAgB;IAC3B,gBAAgB,qBAAqB;IACrC,0BAA0B,+BAA+B;IACzD,+BAA+B,oCAAoC;IACnE,0BAA0B,+BAA+B;IACzD,sBAAsB,2BAA2B;IACjD,sBAAsB,2BAA2B;IACjD,2BAA2B,gCAAgC;IAC3D,2BAA2B,gCAAgC;IAC3D,wBAAwB,6BAA6B;IACrD,cAAc,mBAAmB;IACjC,mBAAmB,wBAAwB;IAC3C,mBAAmB,wBAAwB;IAK3C,YAAY,iBAAiB;IAC7B,iBAAiB,sBAAsB;IACvC,YAAY,iBAAiB;IAC7B,aAAa,kBAAkB;IAC/B,iBAAiB,sBAAsB;IACvC,iBAAiB,sBAAsB;IACvC,WAAW,gBAAgB;IAC3B,mBAAmB,uBAAuB;IAC1C,iBAAiB,qBAAqB;IACtC,sBAAsB,0BAA0B;IAChD,sBAAsB,0BAA0B;IAChD,uBAAuB,4BAA4B;IACnD,aAAa,kBAAkB;IAC/B,cAAc,mBAAmB;IACjC,cAAc,kBAAkB;IAChC,mBAAmB,uBAAuB;IAC1C,qBAAqB,0BAA0B;IAC/C,wBAAwB,6BAA6B;IACrD,eAAe,oBAAoB;IACnC,UAAU,eAAe;IACzB,iBAAiB,sBAAsB;IACvC,gBAAgB,qBAAqB;IACrC,UAAU,eAAe;IACzB,UAAU,eAAe;IAIzB,gBAAgB,qBAAqB;IACrC,eAAe,oBAAoB;IACnC,YAAY,iBAAiB;IAE7B,cAAc,mBAAmB;IACjC,mBAAmB,wBAAwB;IAE3C,oBAAoB,yBAAyB;IAE7C,cAAc,mBAAmB;IAIjC,aAAa,kBAAkB;IAC/B,YAAY,iBAAiB;IAG7B,gBAAgB,qBAAqB;IACrC,UAAU,eAAe;IACzB,cAAc,mBAAmB;IACjC,uBAAuB,4BAA4B;IACnD,kBAAkB,uBAAuB;IACzC,iBAAiB,sBAAsB;IACvC,cAAc,mBAAmB;IAGjC,eAAe,oBAAoB;IACnC,qBAAqB,0BAA0B;IAE/C,0BAA0B,+BAA+B;IACzD,0BAA0B,+BAA+B;IACzD,0BAA0B,+BAA+B;IACzD,0BAA0B,+BAA+B;IACzD,0BAA0B,+BAA+B;IACzD,0BAA0B,+BAA+B;IACzD,iCAAiC,sCAAsC;IACvE,mBAAmB,wBAAwB;IAC3C,mBAAmB,wBAAwB;IAC3C,mBAAmB,wBAAwB;IAC3C,yBAAyB,8BAA8B;IACvD,mBAAmB,wBAAwB;IAC3C,mBAAmB,wBAAwB;IAC3C,yBAAyB,8BAA8B;IACvD,mBAAmB,wBAAwB;IAC3C,mBAAmB,wBAAwB;IAG3C,mBAAmB,wBAAwB;IAC3C,aAAa,kBAAkB;IAC/B,iBAAiB,sBAAsB;CACxC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA6DlB,CAAC;AAEX,MAAM,MAAM,iBAAiB,GAAG,CAAC,OAAO,eAAe,CAAC,CAAC,MAAM,OAAO,eAAe,CAAC,CAAC;AAEvF;;;;GAIG;AACH,oBAAY,eAAe;IACzB,iBAAiB,sBAAsB;IACvC,cAAc,mBAAmB;IACjC,cAAc,mBAAmB;IACjC,kBAAkB,uBAAuB;CAC1C;AAED,oBAAY,cAAc;IAIxB,cAAc,mBAAmB;IACjC,mBAAmB,wBAAwB;IAC3C,iBAAiB,sBAAsB;IACvC,kBAAkB,uBAAuB;IAQzC,wBAAwB,6BAA6B;IACrD,yBAAyB,8BAA8B;IACvD,2BAA2B,gCAAgC;IAC3D,0BAA0B,+BAA+B;IAIzD,uBAAuB,4BAA4B;IACnD,qBAAqB,0BAA0B;IAC/C,uBAAuB,4BAA4B;IACnD,qBAAqB,0BAA0B;CAChD;AAED;;;;GAIG;AACH,oBAAY,aAAa;IACvB,wBAAwB,6BAA6B;CACtD;AAED;;;;;;GAMG;AACH,oBAAY,mBAAmB;IAC7B,uBAAuB,4BAA4B;CACpD;AACD,MAAM,MAAM,qBAAqB,GAAG,GAAG,mBAAmB,EAAE,CAAC;AAE7D;;;;;GAKG;AACH,oBAAY,mBAAmB;IAC7B,mBAAmB,wBAAwB;CAC5C;AACD,MAAM,MAAM,qBAAqB,GAAG,GAAG,mBAAmB,EAAE,CAAC;AAE7D,MAAM,MAAM,WAAW,GACnB,eAAe,GACf,cAAc,GACd,iBAAiB,GACjB,eAAe,GACf,aAAa,GACb,qBAAqB,GACrB,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"enums.d.ts","sourceRoot":"","sources":["../../../src/globals/aiModels/enums.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.EUpscaleVideoModels = exports.EUpscaleImageModels = exports.ESfxGenModels = exports.ETextGenModels = exports.EMusicGenModels = exports.EImageGenModels = exports.EVideoGenModels = void 0;
|
|
3
|
+
exports.EUpscaleVideoModels = exports.EUpscaleImageModels = exports.ESfxGenModels = exports.ETextGenModels = exports.DEFAULT_MUSIC_MODEL = exports.EMusicGenModels = exports.EImageGenModels = exports.EVideoGenModels = void 0;
|
|
4
|
+
exports.resolveMusicModelKey = resolveMusicModelKey;
|
|
4
5
|
var EVideoGenModels;
|
|
5
6
|
(function (EVideoGenModels) {
|
|
6
7
|
EVideoGenModels["PIXVERSE_C1"] = "pixverse-c1";
|
|
@@ -175,6 +176,26 @@ var EMusicGenModels;
|
|
|
175
176
|
EMusicGenModels["GOOGLE_LYRIA_3"] = "google-lyria-3";
|
|
176
177
|
EMusicGenModels["GOOGLE_LYRIA_3_PRO"] = "google-lyria-3-pro";
|
|
177
178
|
})(EMusicGenModels || (exports.EMusicGenModels = EMusicGenModels = {}));
|
|
179
|
+
/**
|
|
180
|
+
* Music keys that can no longer be served, mapped to the live model that
|
|
181
|
+
* replaces them. Resolve every incoming music key through
|
|
182
|
+
* resolveMusicModelKey() so old clients / saved MCP configs keep working.
|
|
183
|
+
* - minimax-music-1.5: MiniMax withdrew the Music API from our account
|
|
184
|
+
* (status 2153 "no longer available to new users", 100% failing since
|
|
185
|
+
* 2026-09-14).
|
|
186
|
+
* - google-lyria-3 / -3-pro: their modelIds (lyria-003, lyria-3-pro) are not
|
|
187
|
+
* Vertex publisher models — GET publishers/google/models/<id> → 404
|
|
188
|
+
* (verified 2026-10-20); lyria-002 is GA and reachable.
|
|
189
|
+
*/
|
|
190
|
+
const RETIRED_MUSIC_MODELS = {
|
|
191
|
+
[EMusicGenModels.MINIMAX_MUSIC_1_5]: EMusicGenModels.GOOGLE_LYRIA_2,
|
|
192
|
+
[EMusicGenModels.GOOGLE_LYRIA_3]: EMusicGenModels.GOOGLE_LYRIA_2,
|
|
193
|
+
[EMusicGenModels.GOOGLE_LYRIA_3_PRO]: EMusicGenModels.GOOGLE_LYRIA_2,
|
|
194
|
+
};
|
|
195
|
+
exports.DEFAULT_MUSIC_MODEL = EMusicGenModels.GOOGLE_LYRIA_2;
|
|
196
|
+
function resolveMusicModelKey(key) {
|
|
197
|
+
return RETIRED_MUSIC_MODELS[key] ?? key;
|
|
198
|
+
}
|
|
178
199
|
var ETextGenModels;
|
|
179
200
|
(function (ETextGenModels) {
|
|
180
201
|
// ── OpenAI ──────────────────────────────────────────────────────────────
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bytedance.d.ts","sourceRoot":"","sources":["../../../../src/globals/aiModels/providers/bytedance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAWxC,eAAO,MAAM,gBAAgB,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,YAAY,CAAC,
|
|
1
|
+
{"version":3,"file":"bytedance.d.ts","sourceRoot":"","sources":["../../../../src/globals/aiModels/providers/bytedance.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,UAAU,CAAC;AAWxC,eAAO,MAAM,gBAAgB,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,YAAY,CAAC,CAmavE,CAAC"}
|
|
@@ -237,6 +237,10 @@ exports.bytedanceConfigs = {
|
|
|
237
237
|
// docs.byteplus.com/en/docs/ModelArk/2607688 + /1544106 (2026-08-09).
|
|
238
238
|
"bytedance-seedance-2.0-mini": {
|
|
239
239
|
modelId: "dreamina-seedance-2-0-mini-260615",
|
|
240
|
+
// BytePlus returns ModelNotOpen until Mini is activated in the Ark console
|
|
241
|
+
// (prod 2026-10). Backend mirror of the frontend's NEXT_PUBLIC_SEEDANCE_MINI_LIVE:
|
|
242
|
+
// set SEEDANCE_MINI_LIVE=true (Doppler + Railway) once activated.
|
|
243
|
+
gatedByEnv: "SEEDANCE_MINI_LIVE",
|
|
240
244
|
type: ["text-to-video", "image-to-video", "video-to-video"],
|
|
241
245
|
acceptedImageFormats: ["image/jpeg", "image/jpg", "image/png"],
|
|
242
246
|
// Same language set as the rest of the Seedance 2.0 series (shared Dreamina pipeline).
|
|
@@ -10,7 +10,9 @@ export interface ModelMatch {
|
|
|
10
10
|
}
|
|
11
11
|
/** False for retired (shut down) and deprecated (still served, no longer
|
|
12
12
|
* offered) models — the gate for every "which models can I pick" list. */
|
|
13
|
-
export declare function isModelOffered(config: Pick<IModelSchema, "retired" | "deprecated"> | undefined): boolean;
|
|
13
|
+
export declare function isModelOffered(config: Pick<IModelSchema, "retired" | "deprecated" | "gatedByEnv"> | undefined): boolean;
|
|
14
|
+
/** False while the model's `gatedByEnv` flag is set but not `"true"`. */
|
|
15
|
+
export declare function isModelEnvEnabled(config: Pick<IModelSchema, "gatedByEnv"> | undefined): boolean;
|
|
14
16
|
/** Return every model whose tier matches. Optionally filter by GenerationType. */
|
|
15
17
|
export declare function getModelsByTier(tier: Tier, type?: GenerationType): ModelMatch[];
|
|
16
18
|
/** Return the cheapest model satisfying (tier, type). Uses cost.fixed → cost.perSecond → 0. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tierHelpers.d.ts","sourceRoot":"","sources":["../../../src/globals/aiModels/tierHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAGzD,OAAO,KAAK,EAAE,cAAc,EAAc,YAAY,EAAE,MAAM,SAAS,CAAC;AAExE;;;GAGG;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED;2EAC2E;AAC3E,wBAAgB,cAAc,
|
|
1
|
+
{"version":3,"file":"tierHelpers.d.ts","sourceRoot":"","sources":["../../../src/globals/aiModels/tierHelpers.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAGzD,OAAO,KAAK,EAAE,cAAc,EAAc,YAAY,EAAE,MAAM,SAAS,CAAC;AAExE;;;GAGG;AAEH,MAAM,WAAW,UAAU;IACzB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,YAAY,CAAC;CACtB;AAED;2EAC2E;AAC3E,wBAAgB,cAAc,CAC5B,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,SAAS,GAAG,YAAY,GAAG,YAAY,CAAC,GAAG,SAAS,GAC9E,OAAO,CAET;AAED,yEAAyE;AACzE,wBAAgB,iBAAiB,CAAC,MAAM,EAAE,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,GAAG,SAAS,GAAG,OAAO,CAG/F;AAED,kFAAkF;AAClF,wBAAgB,eAAe,CAAC,IAAI,EAAE,IAAI,EAAE,IAAI,CAAC,EAAE,cAAc,GAAG,UAAU,EAAE,CAS/E;AAED,+FAA+F;AAC/F,wBAAgB,gBAAgB,CAC9B,IAAI,EAAE,IAAI,EACV,IAAI,EAAE,cAAc,GACnB,UAAU,GAAG,SAAS,CAIxB;AAED,0EAA0E;AAC1E,wBAAgB,eAAe,CAAC,IAAI,EAAE,cAAc,GAAG,UAAU,EAAE,CAMlE;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CAAC,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,SAAS,CAc3E;AAWD;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CACvC,IAAI,GAAE,cAAgC,GACrC,MAAM,CAeR;AAgCD;;;;;;;;;;GAUG;AACH,wBAAgB,oBAAoB,CAClC,QAAQ,EAAE,MAAM,EAChB,eAAe,EAAE,MAAM,GACtB,MAAM,GAAG,IAAI,CASf;AA8DD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,IAAI,CAU1E"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.isModelOffered = isModelOffered;
|
|
4
|
+
exports.isModelEnvEnabled = isModelEnvEnabled;
|
|
4
5
|
exports.getModelsByTier = getModelsByTier;
|
|
5
6
|
exports.getCheapestModel = getCheapestModel;
|
|
6
7
|
exports.getModelsByType = getModelsByType;
|
|
@@ -13,7 +14,12 @@ const creditUnit_1 = require("../creditUnit");
|
|
|
13
14
|
/** False for retired (shut down) and deprecated (still served, no longer
|
|
14
15
|
* offered) models — the gate for every "which models can I pick" list. */
|
|
15
16
|
function isModelOffered(config) {
|
|
16
|
-
return !!config && !config.retired && !config.deprecated;
|
|
17
|
+
return !!config && !config.retired && !config.deprecated && isModelEnvEnabled(config);
|
|
18
|
+
}
|
|
19
|
+
/** False while the model's `gatedByEnv` flag is set but not `"true"`. */
|
|
20
|
+
function isModelEnvEnabled(config) {
|
|
21
|
+
const flag = config?.gatedByEnv;
|
|
22
|
+
return !flag || process.env[flag] === "true";
|
|
17
23
|
}
|
|
18
24
|
/** Return every model whose tier matches. Optionally filter by GenerationType. */
|
|
19
25
|
function getModelsByTier(tier, type) {
|
|
@@ -92,6 +92,13 @@ export interface IModelSchema {
|
|
|
92
92
|
reason: string;
|
|
93
93
|
replacement?: string;
|
|
94
94
|
};
|
|
95
|
+
/**
|
|
96
|
+
* Env flag that must be `"true"` for this model to be offered — for models
|
|
97
|
+
* integrated ahead of provider-side activation (e.g. BytePlus ModelNotOpen).
|
|
98
|
+
* While unset: validateParams rejects it (non-paging), and the planner,
|
|
99
|
+
* fallback chains, capacity spill, repair and MCP list_models skip it.
|
|
100
|
+
*/
|
|
101
|
+
gatedByEnv?: string;
|
|
95
102
|
fields: Record<string, ISchemaField>;
|
|
96
103
|
resolutionRules?: Record<string, string[]>;
|
|
97
104
|
durationRules?: Record<number, string[]>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/globals/aiModels/types.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/globals/aiModels/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,8BAA8B,CAAC;AAEzD,MAAM,MAAM,cAAc,GACtB,eAAe,GACf,gBAAgB,GAChB,gBAAgB,GAChB,gBAAgB,GAChB,cAAc,GACd,gBAAgB,GAChB,UAAU,GACV,cAAc,GACd,eAAe,GACf,eAAe,GACf,gBAAgB,GAChB,aAAa,GACb,aAAa,GACb,aAAa,GACb,eAAe,GACf,eAAe,GACf,eAAe,GACf,eAAe,CAAC;AAEpB;;;;GAIG;AACH,MAAM,WAAW,kBAAkB;IACjC,wFAAwF;IACxF,gBAAgB,EAAE,MAAM,CAAC;IACzB,gDAAgD;IAChD,gBAAgB,EAAE,MAAM,CAAC;IACzB,kEAAkE;IAClE,WAAW,EAAE,WAAW,CAAC;IACzB;;;;OAIG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;;;OAKG;IACH,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC;;;;OAIG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,aAAa,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,GAAG,OAAO,EAAE,CAAC;IAChD,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;IACpC;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,UAAU;IACzB,CAAC,GAAG,EAAE,MAAM,GAAG;QACb,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAAC;KACvB,CAAC;CACH;AAED,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,cAAc,EAAE,CAAC;IACvB;;;;;;;;OAQG;IACH,IAAI,CAAC,EAAE,IAAI,CAAC;IACZ;;;;OAIG;IACH,OAAO,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IACzC;;;;;;OAMG;IACH,UAAU,CAAC,EAAE;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,WAAW,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC;IAClE;;;;;OAKG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,YAAY,CAAC,CAAC;IAErC,eAAe,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IAC3C,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAAC;IACzC,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB;;;OAGG;IACH,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,IAAI,CAAC,EAAE;QACL,SAAS,CAAC,EAAE,MAAM,CAAC;QACnB;;;;WAIG;QACH,YAAY,CAAC,EAAE,MAAM,CAAC;QACtB,WAAW,CAAC,EAAE,MAAM,CAAC;QAKrB,gBAAgB,CAAC,EAAE,MAAM,CAAC;QAC1B,iBAAiB,CAAC,EAAE,MAAM,CAAC;QAC3B,sBAAsB,CAAC,EAAE,MAAM,CAAC;QAChC,KAAK,CAAC,EAAE,UAAU,CAAC;QACnB,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,CAAC,GAAG,EAAE,MAAM,GAAG,GAAG,CAAC;KACpB,CAAC;IACF;;;;;OAKG;IACH,QAAQ,CAAC,EAAE;QACT,mEAAmE;QACnE,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,2DAA2D;QAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;QACf,4CAA4C;QAC5C,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,+CAA+C;QAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,CAAC;IACF,4FAA4F;IAC5F,MAAM,CAAC,EAAE,kBAAkB,CAAC;IAC5B,kHAAkH;IAClH,oBAAoB,CAAC,EAAE,MAAM,EAAE,CAAC;IAChC;;;;;;;;;;OAUG;IACH,wBAAwB,CAAC,EAAE,MAAM,EAAE,CAAC;CACrC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Planner.d.ts","sourceRoot":"","sources":["../../../../src/services/agent/planner/Planner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAoB,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,SAAS,EAEV,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAkB7C;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,SAAS,CAAC;IACf,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,OAAO;IAIN,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAEP,IAAI,EAAE,cAAc;IAK3C,IAAI,CACR,KAAK,EAAE,UAAU,EACjB,IAAI,GAAE;QACJ,OAAO,CAAC,EAAE,YAAY,CAAC;QACvB,QAAQ,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;QACjC,WAAW,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;QACvC,KAAK,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;QAChC;;;;;;WAMG;QACH,cAAc,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;KAC9B,GACL,OAAO,CAAC,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"Planner.d.ts","sourceRoot":"","sources":["../../../../src/services/agent/planner/Planner.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAoB,MAAM,+BAA+B,CAAC;AAC7E,OAAO,EACL,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,SAAS,EAEV,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAChF,OAAO,EAAE,SAAS,EAAE,MAAM,cAAc,CAAC;AAGzC,OAAO,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAkB7C;;;;;;;;;;;GAWG;AAEH,MAAM,WAAW,cAAc;IAC7B,GAAG,EAAE,SAAS,CAAC;IACf,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,qBAAa,OAAO;IAIN,OAAO,CAAC,QAAQ,CAAC,IAAI;IAHjC,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAc;IACrC,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAS;gBAEP,IAAI,EAAE,cAAc;IAK3C,IAAI,CACR,KAAK,EAAE,UAAU,EACjB,IAAI,GAAE;QACJ,OAAO,CAAC,EAAE,YAAY,CAAC;QACvB,QAAQ,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;QACjC,WAAW,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;QACvC,KAAK,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;QAChC;;;;;;WAMG;QACH,cAAc,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;KAC9B,GACL,OAAO,CAAC,SAAS,CAAC;IA8RrB;;;;;;;;;;;OAWG;IACH,UAAU,CACR,KAAK,EAAE,UAAU,EACjB,IAAI,GAAE;QACJ,OAAO,CAAC,EAAE,YAAY,CAAC;QACvB,QAAQ,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;QACjC,WAAW,CAAC,EAAE,iBAAiB,GAAG,IAAI,CAAC;QACvC,KAAK,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;KAC5B,GACL;QAAE,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,CAAC;QAAC,MAAM,EAAE,OAAO,CAAC,SAAS,CAAC,CAAA;KAAE;IAuEhE;;;;;;;;;;;;;;;;OAgBG;IACG,0BAA0B,CAC9B,KAAK,EAAE,YAAY,EACnB,KAAK,EAAE,UAAU,EACjB,IAAI,GAAE;QACJ,OAAO,CAAC,EAAE,YAAY,CAAC;QACvB,QAAQ,CAAC,EAAE,cAAc,GAAG,IAAI,CAAC;QACjC,KAAK,CAAC,EAAE,gBAAgB,GAAG,IAAI,CAAC;QAChC,cAAc,CAAC,EAAE,OAAO,CAAC;QACzB,0EAA0E;QAC1E,WAAW,CAAC,EAAE,MAAM,CAAC;KACjB,GACL,OAAO,CAAC,WAAW,EAAE,CAAC;CAQ1B"}
|
|
@@ -249,6 +249,12 @@ class Planner {
|
|
|
249
249
|
// TTS language and the caption ASR hint, so it must survive even when
|
|
250
250
|
// the LLM omits it (it's marked ORCHESTRATOR-ONLY in the schema).
|
|
251
251
|
reparsed.data.outputLanguage = brief.outputLanguage;
|
|
252
|
+
// The aspect the user picked is a hard constraint, not a hint: the
|
|
253
|
+
// executor renders every scene and the final cut at plan.aspect, so an
|
|
254
|
+
// LLM that drifts to its landscape habit would ship a 16:9 video for a
|
|
255
|
+
// 9:16 request. Overlay deterministically, same as outputLanguage.
|
|
256
|
+
if (brief.aspect)
|
|
257
|
+
reparsed.data.aspect = brief.aspect;
|
|
252
258
|
// Soft-validation pass: vo-clip (if we downgraded after maxRetries)
|
|
253
259
|
// + trailing-silence. These ship with the plan; the UI surfaces them.
|
|
254
260
|
reparsed.data.warnings = (0, validators_1.collectPlanWarnings)(reparsed.data);
|
|
@@ -336,6 +342,9 @@ class Planner {
|
|
|
336
342
|
if (reparsed.success) {
|
|
337
343
|
// Stream path skipped the validators loop; still attach soft warnings.
|
|
338
344
|
reparsed.data.warnings = (0, validators_1.collectPlanWarnings)(reparsed.data);
|
|
345
|
+
// Requested aspect is a hard constraint — see plan().
|
|
346
|
+
if (brief.aspect)
|
|
347
|
+
reparsed.data.aspect = brief.aspect;
|
|
339
348
|
return reparsed.data;
|
|
340
349
|
}
|
|
341
350
|
// Validation tripped on a streamed payload — fall back to retry pass.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"chains.d.ts","sourceRoot":"","sources":["../../../../src/services/agent/providerFallback/chains.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,eAAe,EACf,eAAe,EACf,aAAa,
|
|
1
|
+
{"version":3,"file":"chains.d.ts","sourceRoot":"","sources":["../../../../src/services/agent/providerFallback/chains.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,eAAe,EACf,eAAe,EACf,aAAa,EAGb,KAAK,cAAc,EACpB,MAAM,2BAA2B,CAAC;AAGnC;;;;;;;;;;;;GAYG;AAGH,eAAO,MAAM,sBAAsB,EAAE,SAAS,eAAe,EAY5D,CAAC;AAKF,eAAO,MAAM,sBAAsB,EAAE,SAAS,eAAe,EAW5D,CAAC;AAQF,eAAO,MAAM,uBAAuB,EAAE,SAAS,eAAe,EAW7D,CAAC;AAKF,eAAO,MAAM,uBAAuB,EAAE,SAAS,eAAe,EAU7D,CAAC;AASF,eAAO,MAAM,kBAAkB,EAAE,SAAS,eAAe,EAIxD,CAAC;AAGF,eAAO,MAAM,WAAW,EAAE,SAAS,eAAe,EAIjD,CAAC;AAGF,eAAO,MAAM,SAAS,EAAE,SAAS,aAAa,EAE7C,CAAC;AAEF;;;;;;;;;;GAUG;AACH,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,MAAM,CAAC;IACf,WAAW,EAAE,MAAM,CAAC;IACpB,qDAAqD;IACrD,IAAI,CAAC,EAAE,cAAc,CAAC;IACtB,+EAA+E;IAC/E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,wCAAwC;IACxC,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;;;;;;OAOG;IACH,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB;AAED,wBAAgB,mBAAmB,CACjC,KAAK,EAAE,eAAe,EACtB,GAAG,EAAE,sBAAsB,GAC1B,OAAO,CAyCT;AAED,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CASjD;AA6DD;;;;GAIG;AACH,wBAAgB,wBAAwB,CAAC,CAAC,EAAE,eAAe,GAAG,MAAM,GAAG,MAAM,CAI5E;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,eAAe;IAC9B,iDAAiD;IACjD,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,SAAS,eAAe,EAAE,EACjC,KAAK,EAAE,eAAe,GACrB,eAAe,EAAE,CAInB;AAED;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,GAAG,KAAK,CAOtE;AAED;;;;GAIG;AACH,wBAAgB,eAAe,CAC7B,WAAW,EAAE,eAAe,EAC5B,aAAa,EAAE,SAAS,eAAe,EAAE,GACxC,eAAe,EAAE,CAMnB;AAED;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,MAAM,WAAW,mBAAmB;IAClC,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED,MAAM,WAAW,kBAAkB;IACjC,8CAA8C;IAC9C,YAAY,EAAE,MAAM,CAAC;IACrB,wEAAwE;IACxE,UAAU,EAAE,MAAM,CAAC;IACnB,yDAAyD;IACzD,QAAQ,EAAE,MAAM,CAAC;IACjB,2EAA2E;IAC3E,aAAa,EAAE,OAAO,CAAC;CACxB;AAED,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,MAAM,GAAG,eAAe,EAC/B,WAAW,EAAE,MAAM,EACnB,IAAI,GAAE,mBAAwB,GAC7B,kBAAkB,GAAG,IAAI,CAyB3B"}
|
|
@@ -99,7 +99,8 @@ exports.AVATAR_VIDEO_CHAIN = [
|
|
|
99
99
|
// ── Music: search/gen ─────────────────────────────────────────────────
|
|
100
100
|
exports.MUSIC_CHAIN = [
|
|
101
101
|
aiModels_1.EMusicGenModels.GOOGLE_LYRIA_2,
|
|
102
|
-
|
|
102
|
+
// REMOVED FOR v1 — kept for reference: MiniMax Music API withdrawn (2153).
|
|
103
|
+
// EMusicGenModels.MINIMAX_MUSIC_1_5,
|
|
103
104
|
];
|
|
104
105
|
// ── SFX: ElevenLabs only ──────────────────────────────────────────────
|
|
105
106
|
exports.SFX_CHAIN = [
|
|
@@ -109,6 +110,9 @@ function isVideoModelCapable(model, req) {
|
|
|
109
110
|
const cfg = aiModels_1.aiModelConfigs[model];
|
|
110
111
|
if (!cfg)
|
|
111
112
|
return true; // unknown model → optimistic
|
|
113
|
+
// Not offered (retired / env-gated pending provider activation) → can't serve.
|
|
114
|
+
if (!(0, aiModels_1.isModelOffered)(cfg))
|
|
115
|
+
return false;
|
|
112
116
|
// Type gate (text-to-video vs image-to-video).
|
|
113
117
|
if (req.type && cfg.type && !cfg.type.includes(req.type))
|
|
114
118
|
return false;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"searchUserLibrary.tool.d.ts","sourceRoot":"","sources":["../../../../src/services/agent/tools/searchUserLibrary.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAgB,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE/D;;;;;;;GAOG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,aAAa,GAAG,aAAa,CAAC;IAClE,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;CACf,KAAK,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;AAGlC,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,mBAAmB,GAAG,IAAI,CAElE;AAED,QAAA,MAAM,WAAW;;;;;;;;;;iBASf,CAAC;AAEH,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;iBAahB,CAAC;AAEH,eAAO,MAAM,qBAAqB,EAAE,cAAc,CAChD,OAAO,WAAW,EAClB,OAAO,YAAY,
|
|
1
|
+
{"version":3,"file":"searchUserLibrary.tool.d.ts","sourceRoot":"","sources":["../../../../src/services/agent/tools/searchUserLibrary.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAgB,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAE/D;;;;;;;GAOG;AAEH,MAAM,WAAW,gBAAgB;IAC/B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,aAAa,GAAG,aAAa,CAAC;IAClE,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,MAAM,MAAM,mBAAmB,GAAG,CAAC,MAAM,EAAE;IACzC,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,gBAAgB,CAAC,MAAM,CAAC,CAAC;IAChC,KAAK,EAAE,MAAM,CAAC;CACf,KAAK,OAAO,CAAC,gBAAgB,EAAE,CAAC,CAAC;AAGlC,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,mBAAmB,GAAG,IAAI,CAElE;AAED,QAAA,MAAM,WAAW;;;;;;;;;;iBASf,CAAC;AAEH,QAAA,MAAM,YAAY;;;;;;;;;;;;;;;;;iBAahB,CAAC;AAEH,eAAO,MAAM,qBAAqB,EAAE,cAAc,CAChD,OAAO,WAAW,EAClB,OAAO,YAAY,CAiCpB,CAAC"}
|
|
@@ -52,7 +52,13 @@ exports.searchUserLibraryTool = {
|
|
|
52
52
|
kind: input.kind,
|
|
53
53
|
limit: input.limit,
|
|
54
54
|
});
|
|
55
|
-
|
|
55
|
+
// Only real, fetchable media is a library asset. The Firestore searcher
|
|
56
|
+
// scans projectJson clips, and the run's own C23 shell write (plus any
|
|
57
|
+
// earlier failed project) carries skeleton clips whose src is the
|
|
58
|
+
// `data:,placeholder` sentinel — a valid URL to zod, so a user-asset scene
|
|
59
|
+
// "found" it, succeeded with no visual, and the auto-render then failed
|
|
60
|
+
// with SCENES_NOT_READY (prod 2026-10-15). Drop anything not http(s).
|
|
61
|
+
return { assets: assets.filter((a) => /^https?:\/\//i.test(a.url)) };
|
|
56
62
|
},
|
|
57
63
|
};
|
|
58
64
|
(0, toolRegistry_1.registerTool)(exports.searchUserLibraryTool);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/services/aiGen/helpers.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGhE;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,IAAI,MAAM,EAAE,CAEvD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAG3E;AAED,gFAAgF;AAChF,6FAA6F;AAC7F,MAAM,WAAW,uBAAuB;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qFAAqF;IACrF,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,4DAA4D;IAC5D,0BAA0B,CAAC,EAAE,MAAM,EAAE,CAAC;IACtC,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,uBAAuB,GAAG;IAClE,aAAa,EAAE,OAAO,CAAC;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,cAAc,EAAE,MAAM,CAAC;CACxB,CAqBA;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGxD;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../../src/services/aiGen/helpers.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,qBAAqB,EAAE,MAAM,mBAAmB,CAAC;AAE1D;;;;;;;GAOG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGhE;AAED;;;;GAIG;AACH,wBAAgB,4BAA4B,IAAI,MAAM,EAAE,CAEvD;AAED;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAG3E;AAED,gFAAgF;AAChF,6FAA6F;AAC7F,MAAM,WAAW,uBAAuB;IACtC,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,qFAAqF;IACrF,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,4DAA4D;IAC5D,0BAA0B,CAAC,EAAE,MAAM,EAAE,CAAC;IACtC,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;IAElB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,iBAAiB,CAAC,EAAE,MAAM,CAAC;IAC3B,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC9B,iFAAiF;IACjF,kBAAkB,CAAC,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,GAAG,EAAE,uBAAuB,GAAG;IAClE,aAAa,EAAE,OAAO,CAAC;IACvB,qBAAqB,CAAC,EAAE,MAAM,CAAC;IAC/B;;;;;OAKG;IACH,cAAc,EAAE,MAAM,CAAC;IACvB,8EAA8E;IAC9E,cAAc,EAAE,MAAM,CAAC;CACxB,CAqBA;AAED,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAGxD;AAED,wBAAgB,cAAc,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAsLrE"}
|
|
@@ -83,6 +83,11 @@ function validateParams(params) {
|
|
|
83
83
|
if (modelConfig.retired) {
|
|
84
84
|
throw new errors_1.UserFacingError(`Model ${params.modelKey} is no longer available: ${modelConfig.retired.reason} Please pick a different model.`, errors_1.USER_FACING_ERROR_CODES.CAPABILITY_MISMATCH);
|
|
85
85
|
}
|
|
86
|
+
// 0b. Integrated but not yet activated provider-side (gatedByEnv unset) —
|
|
87
|
+
// same non-paging rejection instead of a provider ModelNotOpen round-trip.
|
|
88
|
+
if (!(0, aiModels_1.isModelEnvEnabled)(modelConfig)) {
|
|
89
|
+
throw new errors_1.UserFacingError(`Model ${params.modelKey} isn't available yet. Please pick a different model.`, errors_1.USER_FACING_ERROR_CODES.CAPABILITY_MISMATCH);
|
|
90
|
+
}
|
|
86
91
|
const errors = [];
|
|
87
92
|
// 1. Field-level validation (required + allowedValues)
|
|
88
93
|
for (const [field, rules] of Object.entries(modelConfig.fields)) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"alibaba.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/alibaba/alibaba.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"alibaba.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/alibaba/alibaba.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAoGlB;;;;;;GAMG;AACH,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,MAAM,EAAE,qBAAqB,GAC5B;IAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAA;CAAE,CAgJzE;AA2CD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,WAAW,EAAE,MAAM,GAClB,MAAM,GAAG,SAAS,CAmBpB;AAED,qBAAa,cAAe,SAAQ,wBAAwB;IAE1D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAwB;IAChD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAS;;IAiBjC;;;;OAIG;YACW,OAAO;IA8Df,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;YAyInB,WAAW;IAwBnB,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,EACzB,QAAQ,GACT,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA8EjD;;;;;;;;;;;;;;;;;;;;;OAqBG;IACG,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA6EjC;;;OAGG;YACW,iBAAiB;IAoD/B;;;OAGG;YACW,kBAAkB;IAmEhC,aAAa,CAAC,EACZ,QAAQ,EACR,UAAU,EACV,WAAW,EACX,QAAQ,EACR,SAAiB,EACjB,SAAa,EACb,WAAW,EACX,aAAa,EACb,qBAAqB,EACrB,KAAK,EACL,cAAc,GACf,EAAE,iBAAiB,GAAG,MAAM;CA4C9B"}
|
|
@@ -16,6 +16,18 @@ const helpers_2 = require("../../helpers");
|
|
|
16
16
|
const utils_1 = require("../../../../utils");
|
|
17
17
|
const logger_1 = require("../../../../utils/logger");
|
|
18
18
|
const errors_1 = require("../../../../utils/errors");
|
|
19
|
+
/**
|
|
20
|
+
* DashScope content-safety rejections ("Green" is Alibaba's moderation
|
|
21
|
+
* service). Seen as code DataInspectionFailed / message "Green net check
|
|
22
|
+
* rejected text (input)" or "…may contain inappropriate content" — on submit
|
|
23
|
+
* (HTTP 400 body) and on poll (task FAILED). The user's prompt/image, not a
|
|
24
|
+
* system fault: surface as CONTENT_POLICY_VIOLATION so it doesn't page.
|
|
25
|
+
*/
|
|
26
|
+
function isDashScopeModeration(code, message) {
|
|
27
|
+
if (code && /DataInspection|IPInfringement|InappropriateContent/i.test(code))
|
|
28
|
+
return true;
|
|
29
|
+
return !!message && /green net|data inspection|inappropriate content/i.test(message);
|
|
30
|
+
}
|
|
19
31
|
// Endpoint topology (verified 2026-06-06 against intl docs + live probes):
|
|
20
32
|
//
|
|
21
33
|
// T2V + I2V → /services/aigc/video-generation/video-synthesis (async; X-DashScope-Async: enable)
|
|
@@ -339,6 +351,9 @@ class AlibabaService extends baseAiGenProvider_service_1.BaseAiGenProviderServic
|
|
|
339
351
|
// stored job errorMessage.
|
|
340
352
|
const axiosErr = err;
|
|
341
353
|
const data = axiosErr.response?.data;
|
|
354
|
+
if (data && isDashScopeModeration(data.code, data.message)) {
|
|
355
|
+
throw new errors_1.UserFacingError((0, errors_1.friendlyMessageForCode)(errors_1.USER_FACING_ERROR_CODES.CONTENT_POLICY_VIOLATION), errors_1.USER_FACING_ERROR_CODES.CONTENT_POLICY_VIOLATION);
|
|
356
|
+
}
|
|
342
357
|
if (data && (data.code || data.message)) {
|
|
343
358
|
logger_1.logger.error("Alibaba DashScope request failed", {
|
|
344
359
|
url,
|
|
@@ -547,6 +562,15 @@ class AlibabaService extends baseAiGenProvider_service_1.BaseAiGenProviderServic
|
|
|
547
562
|
}
|
|
548
563
|
}
|
|
549
564
|
if (status === "FAILED" || status === "failed") {
|
|
565
|
+
if (isDashScopeModeration(result.output?.code, result.output?.message)) {
|
|
566
|
+
return {
|
|
567
|
+
status: types_1.EVideoSceneStatus.FAILED,
|
|
568
|
+
errorMessage: JSON.stringify({
|
|
569
|
+
code: errors_1.USER_FACING_ERROR_CODES.CONTENT_POLICY_VIOLATION,
|
|
570
|
+
message: (0, errors_1.friendlyMessageForCode)(errors_1.USER_FACING_ERROR_CODES.CONTENT_POLICY_VIOLATION),
|
|
571
|
+
}),
|
|
572
|
+
};
|
|
573
|
+
}
|
|
550
574
|
return {
|
|
551
575
|
status: types_1.EVideoSceneStatus.FAILED,
|
|
552
576
|
errorMessage: result.output?.message || "Video generation failed",
|
|
@@ -722,6 +746,9 @@ class AlibabaService extends baseAiGenProvider_service_1.BaseAiGenProviderServic
|
|
|
722
746
|
break;
|
|
723
747
|
}
|
|
724
748
|
if (status === "FAILED" || status === "failed") {
|
|
749
|
+
if (isDashScopeModeration(poll?.output?.code, poll?.output?.message)) {
|
|
750
|
+
throw new errors_1.UserFacingError((0, errors_1.friendlyMessageForCode)(errors_1.USER_FACING_ERROR_CODES.CONTENT_POLICY_VIOLATION), errors_1.USER_FACING_ERROR_CODES.CONTENT_POLICY_VIOLATION);
|
|
751
|
+
}
|
|
725
752
|
throw new Error(`DashScope image task failed: ${poll?.output?.message ?? "unknown"}`);
|
|
726
753
|
}
|
|
727
754
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bytedance.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/bytedance/bytedance.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AA8BlB;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQlF;AAsBD,qBAAa,gBAAiB,SAAQ,wBAAwB;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CACsD;IAQ9E,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,WAAW;IAIb,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;
|
|
1
|
+
{"version":3,"file":"bytedance.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/bytedance/bytedance.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AA8BlB;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,WAAW,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQlF;AAsBD,qBAAa,gBAAiB,SAAQ,wBAAwB;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CACsD;IAQ9E,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,WAAW;IAIb,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAyR3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAkJjD;;;;;;;;;;;OAWG;IACG,aAAa,CAAC,MAAM,EAAE,qBAAqB,GAAG,OAAO,CAAC,qBAAqB,CAAC;IAyIlF,+EAA+E;YACjE,mBAAmB;IAoCjC;;;OAGG;YACW,eAAe;IAgD7B,aAAa,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM;CAsFjD"}
|
|
@@ -273,6 +273,12 @@ class ByteDanceService extends baseAiGenProvider_service_1.BaseAiGenProviderServ
|
|
|
273
273
|
}
|
|
274
274
|
throw new errors_1.UserFacingError(`Your input image is not valid: ${message}`, errors_1.USER_FACING_ERROR_CODES.INPUT_IMAGE_REJECTED);
|
|
275
275
|
}
|
|
276
|
+
// Model not activated on our Ark account (prod 2026-10, 2.0 Mini).
|
|
277
|
+
// Operator action (activate in the Ark console) — PROVIDER_AUTH_ERROR
|
|
278
|
+
// still pages, but the user gets the canned message, not Ark internals.
|
|
279
|
+
if (code === "ModelNotOpen" || code?.startsWith("ModelNotOpen")) {
|
|
280
|
+
throw new errors_1.UserFacingError(`ByteDance model ${modelId} is not activated on the Ark account: ${message}`, errors_1.USER_FACING_ERROR_CODES.PROVIDER_AUTH_ERROR);
|
|
281
|
+
}
|
|
276
282
|
throw new Error(`ByteDance generateVideo failed (${resp.status}): ${errText}`);
|
|
277
283
|
}
|
|
278
284
|
const data = await resp.json();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"googleMusic.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/google/googleMusic.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAExE;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,
|
|
1
|
+
{"version":3,"file":"googleMusic.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/google/googleMusic.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAC;AAExE;;;;;;;;;;;GAWG;AACH,wBAAsB,mBAAmB,CACvC,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC,CA6EhC"}
|
|
@@ -19,13 +19,26 @@ const storage_1 = require("../../../../libs/storage");
|
|
|
19
19
|
async function generateGoogleMusic(params) {
|
|
20
20
|
const modelConfig = aiModels_1.aiModelConfigs[params.modelKey];
|
|
21
21
|
const modelId = modelConfig?.modelId ?? "lyria-002";
|
|
22
|
-
|
|
22
|
+
// Prod never set GCP_PROJECT_ID, so every Lyria call threw before reaching
|
|
23
|
+
// Vertex. Fall back to the runtime project (Cloud Functions sets
|
|
24
|
+
// GCLOUD_PROJECT) and then the backend service account's own project.
|
|
25
|
+
const clientEmail = process.env.GOOGLE_CLIENT_EMAIL;
|
|
26
|
+
const privateKey = process.env.GOOGLE_PRIVATE_KEY;
|
|
27
|
+
const projectId = process.env.GCP_PROJECT_ID ||
|
|
28
|
+
process.env.GOOGLE_CLOUD_PROJECT ||
|
|
29
|
+
process.env.GCLOUD_PROJECT ||
|
|
30
|
+
clientEmail?.match(/@([^.]+)\.iam\.gserviceaccount\.com$/)?.[1];
|
|
23
31
|
if (!projectId) {
|
|
24
32
|
throw new Error("Missing GCP_PROJECT_ID env var (required for Vertex Lyria)");
|
|
25
33
|
}
|
|
26
34
|
const location = process.env.GCP_LOCATION ?? "us-central1";
|
|
35
|
+
// Railway has no ADC — use the backend service account from env when it's
|
|
36
|
+
// there (same creds GCPService uses); otherwise ADC (Cloud Functions SA).
|
|
27
37
|
const auth = new google_auth_library_1.GoogleAuth({
|
|
28
38
|
scopes: ["https://www.googleapis.com/auth/cloud-platform"],
|
|
39
|
+
...(clientEmail && privateKey
|
|
40
|
+
? { credentials: { client_email: clientEmail, private_key: privateKey.replace(/\\n/g, "\n") } }
|
|
41
|
+
: {}),
|
|
29
42
|
});
|
|
30
43
|
const client = await auth.getClient();
|
|
31
44
|
const tokenRes = await client.getAccessToken();
|
|
@@ -5,7 +5,7 @@ export declare class RunwayService extends BaseAiGenProviderService {
|
|
|
5
5
|
private readonly apiKey;
|
|
6
6
|
constructor();
|
|
7
7
|
private request;
|
|
8
|
-
generateVideo(
|
|
8
|
+
generateVideo(rawParams: VideoGenerationParams): Promise<VideoGenerationResult>;
|
|
9
9
|
checkVideoStatus({ task, outputFilename, outputFilePath, }: VideoStatusParams): Promise<VideoStatusResult>;
|
|
10
10
|
getCreditUsed({ modelKey, duration, multiClip, numImages, aspectRatio, creditFloor, resolution, audio, hasInputVideo, inputVideoDurationSec, numInputImages, numInputAudios, }: CreditUsageParams): number;
|
|
11
11
|
/**
|
|
@@ -17,6 +17,6 @@ export declare class RunwayService extends BaseAiGenProviderService {
|
|
|
17
17
|
* Runway requires concrete pixel ratios (`"1920:1080"` etc.) per the
|
|
18
18
|
* Gen-4 Image spec.
|
|
19
19
|
*/
|
|
20
|
-
generateImage(
|
|
20
|
+
generateImage(rawParams: ImageGenerationParams): Promise<ImageGenerationResult>;
|
|
21
21
|
}
|
|
22
22
|
//# sourceMappingURL=runway.service.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"runway.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/runway/runway.service.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;
|
|
1
|
+
{"version":3,"file":"runway.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/runway/runway.service.ts"],"names":[],"mappings":"AAOA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAiFlB,qBAAa,aAAc,SAAQ,wBAAwB;IACzD,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAqC;IAC7D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;;YAUlB,OAAO;IA0Df,aAAa,CACjB,SAAS,EAAE,qBAAqB,GAC/B,OAAO,CAAC,qBAAqB,CAAC;IA0J3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAuDjD,aAAa,CAAC,EACZ,QAAQ,EACR,QAAY,EACZ,SAAiB,EACjB,SAAa,EACb,WAAW,EACX,WAAW,EACX,UAAU,EACV,KAAK,EACL,aAAa,EACb,qBAAqB,EACrB,cAAkB,EAClB,cAAkB,GACnB,EAAE,iBAAiB,GAAG,MAAM;IAwD7B;;;;;;;;OAQG;IACG,aAAa,CACjB,SAAS,EAAE,qBAAqB,GAC/B,OAAO,CAAC,qBAAqB,CAAC;CAgFlC"}
|
|
@@ -16,6 +16,73 @@ const types_2 = require("./types");
|
|
|
16
16
|
const errors_1 = require("../../../../utils/errors");
|
|
17
17
|
const cameraAdapter_1 = require("./cameraAdapter");
|
|
18
18
|
const hostedModels_1 = require("./hostedModels");
|
|
19
|
+
// Runway only fetches assets served with an image Content-Type. Some of our
|
|
20
|
+
// own objects are served as application/octet-stream (a missing type at
|
|
21
|
+
// upload time), and Runway 400s on them (prod 2026-10-10, grok-imagine-1.5).
|
|
22
|
+
const RUNWAY_IMAGE_TYPES = new Set(["image/jpeg", "image/png", "image/webp"]);
|
|
23
|
+
function sniffImageType(buf) {
|
|
24
|
+
if (buf.length >= 3 && buf[0] === 0xff && buf[1] === 0xd8 && buf[2] === 0xff)
|
|
25
|
+
return "image/jpeg";
|
|
26
|
+
if (buf.length >= 8 && buf.subarray(0, 8).equals(Buffer.from([0x89, 0x50, 0x4e, 0x47, 0x0d, 0x0a, 0x1a, 0x0a]))) {
|
|
27
|
+
return "image/png";
|
|
28
|
+
}
|
|
29
|
+
if (buf.length >= 12 && buf.toString("ascii", 0, 4) === "RIFF" && buf.toString("ascii", 8, 12) === "WEBP") {
|
|
30
|
+
return "image/webp";
|
|
31
|
+
}
|
|
32
|
+
return null;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Return `uri` unchanged when Runway will accept it; otherwise re-host the
|
|
36
|
+
* bytes under the sniffed image type and return the new URL. Best-effort: on
|
|
37
|
+
* any probe failure the original URI is passed through, so Runway's own error
|
|
38
|
+
* (not ours) is what surfaces.
|
|
39
|
+
*/
|
|
40
|
+
async function ensureRunwayImageUri(uri) {
|
|
41
|
+
if (uri.startsWith("data:"))
|
|
42
|
+
return uri;
|
|
43
|
+
try {
|
|
44
|
+
const head = await axios_1.default.get(uri, {
|
|
45
|
+
responseType: "arraybuffer",
|
|
46
|
+
headers: { Range: "bytes=0-0" },
|
|
47
|
+
timeout: 15000,
|
|
48
|
+
validateStatus: () => true,
|
|
49
|
+
});
|
|
50
|
+
const served = String(head.headers["content-type"] ?? "").split(";")[0].trim().toLowerCase();
|
|
51
|
+
if (RUNWAY_IMAGE_TYPES.has(served))
|
|
52
|
+
return uri;
|
|
53
|
+
const full = await axios_1.default.get(uri, { responseType: "arraybuffer", timeout: 60000 });
|
|
54
|
+
const buf = Buffer.from(full.data);
|
|
55
|
+
const sniffed = sniffImageType(buf);
|
|
56
|
+
if (!sniffed) {
|
|
57
|
+
logger_1.logger.warn("Runway input image has an unsupported type; passing through", { served, uri: uri.slice(0, 160) });
|
|
58
|
+
return uri;
|
|
59
|
+
}
|
|
60
|
+
const ext = sniffed.split("/")[1];
|
|
61
|
+
const path = `images/runway-inputs/${Date.now()}-${Math.random().toString(36).slice(2, 8)}.${ext}`;
|
|
62
|
+
const rehosted = await storage_1.mediaStorage.put(path, buf, sniffed);
|
|
63
|
+
logger_1.logger.info("Runway input image re-hosted with a proper Content-Type", { served, sniffed, path });
|
|
64
|
+
return rehosted;
|
|
65
|
+
}
|
|
66
|
+
catch (err) {
|
|
67
|
+
logger_1.logger.warn("Runway input image probe failed; passing through", {
|
|
68
|
+
uri: uri.slice(0, 160),
|
|
69
|
+
err: err instanceof Error ? err.message : String(err),
|
|
70
|
+
});
|
|
71
|
+
return uri;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
async function withRunwayImageUris(params) {
|
|
75
|
+
const out = { ...params };
|
|
76
|
+
await Promise.all([
|
|
77
|
+
out.inputImageUrl && ensureRunwayImageUri(out.inputImageUrl).then((u) => { out.inputImageUrl = u; }),
|
|
78
|
+
out.lastFrameImageUrl && ensureRunwayImageUri(out.lastFrameImageUrl).then((u) => { out.lastFrameImageUrl = u; }),
|
|
79
|
+
out.referenceImageUrls &&
|
|
80
|
+
Promise.all(out.referenceImageUrls.map(ensureRunwayImageUri)).then((u) => { out.referenceImageUrls = u; }),
|
|
81
|
+
out.inputImageUrls &&
|
|
82
|
+
Promise.all(out.inputImageUrls.map(ensureRunwayImageUri)).then((u) => { out.inputImageUrls = u; }),
|
|
83
|
+
]);
|
|
84
|
+
return out;
|
|
85
|
+
}
|
|
19
86
|
class RunwayService extends baseAiGenProvider_service_1.BaseAiGenProviderService {
|
|
20
87
|
constructor() {
|
|
21
88
|
super();
|
|
@@ -49,12 +116,22 @@ class RunwayService extends baseAiGenProvider_service_1.BaseAiGenProviderService
|
|
|
49
116
|
if (tooLong) {
|
|
50
117
|
throw new errors_1.UserFacingError(`Your prompt is too long for this model${tooLong.maximum ? ` (max ${tooLong.maximum} characters)` : ""}. Please shorten it and try again.`, errors_1.USER_FACING_ERROR_CODES.PROMPT_TOO_LONG);
|
|
51
118
|
}
|
|
119
|
+
// OUR Runway account is out of credits (prod 2026-10, 400 "You do not
|
|
120
|
+
// have enough credits to run this task."). Ops must top up — classify as
|
|
121
|
+
// ACCOUNT_QUOTA_EXCEEDED so it still pages (errorPaging excludes that
|
|
122
|
+
// code from the quiet set) but the user sees the canned "pick another
|
|
123
|
+
// model" message instead of raw provider text.
|
|
124
|
+
const errText = typeof response.data?.error === "string" ? response.data.error : "";
|
|
125
|
+
if (/not have enough credits|insufficient credits/i.test(errText)) {
|
|
126
|
+
throw new errors_1.UserFacingError("This video model is temporarily unavailable. You haven't been charged — please pick a different model or retry shortly.", errors_1.USER_FACING_ERROR_CODES.ACCOUNT_QUOTA_EXCEEDED);
|
|
127
|
+
}
|
|
52
128
|
throw new Error(`Runway API Error: ${response.status} ${response.statusText} - ${JSON.stringify(response.data)}`);
|
|
53
129
|
}
|
|
54
130
|
return response.data;
|
|
55
131
|
}
|
|
56
|
-
async generateVideo(
|
|
57
|
-
(0, helpers_2.validateParams)(
|
|
132
|
+
async generateVideo(rawParams) {
|
|
133
|
+
(0, helpers_2.validateParams)(rawParams);
|
|
134
|
+
const params = await withRunwayImageUris(rawParams);
|
|
58
135
|
const modelId = aiModels_1.aiModelConfigs[params.modelKey]?.modelId;
|
|
59
136
|
if (!modelId)
|
|
60
137
|
throw new Error(`Unknown modelKey: ${params.modelKey}`);
|
|
@@ -298,7 +375,8 @@ class RunwayService extends baseAiGenProvider_service_1.BaseAiGenProviderService
|
|
|
298
375
|
* Runway requires concrete pixel ratios (`"1920:1080"` etc.) per the
|
|
299
376
|
* Gen-4 Image spec.
|
|
300
377
|
*/
|
|
301
|
-
async generateImage(
|
|
378
|
+
async generateImage(rawParams) {
|
|
379
|
+
const params = await withRunwayImageUris(rawParams);
|
|
302
380
|
const modelConfig = aiModels_1.aiModelConfigs[params.modelKey];
|
|
303
381
|
const modelId = modelConfig?.modelId;
|
|
304
382
|
if (!modelId)
|
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import { Job } from "bullmq";
|
|
2
2
|
import { RedisOptions } from "ioredis";
|
|
3
|
+
export declare class EnqueueTimeoutError extends Error {
|
|
4
|
+
constructor();
|
|
5
|
+
}
|
|
3
6
|
export type JobData = Record<string, any>;
|
|
4
7
|
interface BullMQServiceOptions {
|
|
5
8
|
redisOptions: RedisOptions;
|
|
@@ -89,6 +92,14 @@ declare class BullMQService {
|
|
|
89
92
|
count?: number;
|
|
90
93
|
};
|
|
91
94
|
}): Promise<void>;
|
|
95
|
+
/**
|
|
96
|
+
* After an enqueue timeout, drop the (likely half-open) shared connection so
|
|
97
|
+
* the next call dials a fresh one — and so the stalled command is rejected
|
|
98
|
+
* rather than flushed late. Only in producer-only processes: a worker host
|
|
99
|
+
* shares this connection with its Workers, so tearing it down there would
|
|
100
|
+
* kill job processing; there we just surface the timeout.
|
|
101
|
+
*/
|
|
102
|
+
private resetProducerConnection;
|
|
92
103
|
/** Get (or lazily create) the Queue handle for a name, reusing the cache. */
|
|
93
104
|
private getQueue;
|
|
94
105
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bullmq.service.d.ts","sourceRoot":"","sources":["../../src/services/bullmq.service.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,GAAG,EAAE,MAAM,QAAQ,CAAC;AAC5C,OAAgB,EAAwB,YAAY,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"bullmq.service.d.ts","sourceRoot":"","sources":["../../src/services/bullmq.service.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,11 +3,39 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
3
3
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
4
|
};
|
|
5
5
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.bullmq = void 0;
|
|
6
|
+
exports.bullmq = exports.EnqueueTimeoutError = void 0;
|
|
7
7
|
// libs/bullmqService.ts
|
|
8
8
|
const bullmq_1 = require("bullmq");
|
|
9
9
|
const ioredis_1 = __importDefault(require("ioredis"));
|
|
10
10
|
const logger_1 = require("../utils/logger");
|
|
11
|
+
const errors_1 = require("../utils/errors");
|
|
12
|
+
/** Upper bound for a single enqueue (init + add) before we give up. */
|
|
13
|
+
const ENQUEUE_TIMEOUT_MS = 20000;
|
|
14
|
+
class EnqueueTimeoutError extends Error {
|
|
15
|
+
constructor() {
|
|
16
|
+
super(`Job enqueue timed out after ${ENQUEUE_TIMEOUT_MS}ms`);
|
|
17
|
+
this.name = "EnqueueTimeoutError";
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
exports.EnqueueTimeoutError = EnqueueTimeoutError;
|
|
21
|
+
async function withEnqueueTimeout(work, onTimeout) {
|
|
22
|
+
let timer;
|
|
23
|
+
const timeout = new Promise((_, reject) => {
|
|
24
|
+
timer = setTimeout(() => {
|
|
25
|
+
onTimeout();
|
|
26
|
+
reject(new EnqueueTimeoutError());
|
|
27
|
+
}, ENQUEUE_TIMEOUT_MS);
|
|
28
|
+
});
|
|
29
|
+
// A late rejection of `work` after the timeout won (e.g. "Connection is
|
|
30
|
+
// closed" from the reset) must not surface as an unhandled rejection.
|
|
31
|
+
work.catch(() => undefined);
|
|
32
|
+
try {
|
|
33
|
+
return await Promise.race([work, timeout]);
|
|
34
|
+
}
|
|
35
|
+
finally {
|
|
36
|
+
clearTimeout(timer);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
11
39
|
const redisOptions_1 = require("./redisOptions");
|
|
12
40
|
// Transient ioredis socket errors that BullMQ's worker `error` event surfaces
|
|
13
41
|
// verbatim. ioredis reconnects from these on its own — they're noise, not
|
|
@@ -121,23 +149,48 @@ class BullMQService {
|
|
|
121
149
|
logger_1.logger.info("[BullMQ] enqueue skipped (dev): set ENABLE_QUEUE=true to enqueue", { queueName, jobId: opts?.jobId });
|
|
122
150
|
return;
|
|
123
151
|
}
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
await
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
152
|
+
// Bounded enqueue. sharedRedisOptions (maxRetriesPerRequest: null +
|
|
153
|
+
// offline queue) lets a command wait FOREVER on a dead/half-open socket —
|
|
154
|
+
// prod 2026-10 saw bullmq.addJob(VIDEO_JOBS) take 86 min inside a
|
|
155
|
+
// Functions request (user charged, video stuck QUEUED). Fail fast instead
|
|
156
|
+
// so the caller can refund and tell the user to retry.
|
|
157
|
+
await withEnqueueTimeout((async () => {
|
|
158
|
+
if (!this.initialized)
|
|
159
|
+
await this.init();
|
|
160
|
+
await this.getQueue(queueName).add(opts?.jobId || "default", data, {
|
|
161
|
+
delay: opts?.delay,
|
|
162
|
+
attempts: opts?.attempts,
|
|
163
|
+
backoff: opts?.backoff,
|
|
164
|
+
// Auto-evict finished jobs so their hashes don't accumulate forever.
|
|
165
|
+
// Without this BullMQ keeps every completed/failed job hash with no TTL
|
|
166
|
+
// (this is what filled prod Redis to ~75% of 30MB / 41k orphan keys).
|
|
167
|
+
// Completed: keep 1 day or last 1000. Failed: keep longer (7 days /
|
|
168
|
+
// last 5000) since failures are worth inspecting.
|
|
169
|
+
removeOnComplete: opts?.removeOnComplete ?? { age: 24 * 3600, count: 1000 },
|
|
170
|
+
removeOnFail: opts?.removeOnFail ?? { age: 7 * 24 * 3600, count: 5000 },
|
|
171
|
+
});
|
|
172
|
+
})(), () => this.resetProducerConnection(queueName));
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* After an enqueue timeout, drop the (likely half-open) shared connection so
|
|
176
|
+
* the next call dials a fresh one — and so the stalled command is rejected
|
|
177
|
+
* rather than flushed late. Only in producer-only processes: a worker host
|
|
178
|
+
* shares this connection with its Workers, so tearing it down there would
|
|
179
|
+
* kill job processing; there we just surface the timeout.
|
|
180
|
+
*/
|
|
181
|
+
resetProducerConnection(queueName) {
|
|
182
|
+
logger_1.logger.error("[BullMQ] enqueue timed out", {
|
|
183
|
+
queueName,
|
|
184
|
+
timeoutMs: ENQUEUE_TIMEOUT_MS,
|
|
185
|
+
producerOnly: this.workers.length === 0,
|
|
140
186
|
});
|
|
187
|
+
if (this.workers.length > 0 || !this.connection)
|
|
188
|
+
return;
|
|
189
|
+
const stale = this.connection;
|
|
190
|
+
this.connection = undefined;
|
|
191
|
+
this.queues.clear();
|
|
192
|
+
this.initialized = false;
|
|
193
|
+
stale.disconnect();
|
|
141
194
|
}
|
|
142
195
|
/** Get (or lazily create) the Queue handle for a name, reusing the cache. */
|
|
143
196
|
getQueue(queueName) {
|
|
@@ -239,13 +292,21 @@ class BullMQService {
|
|
|
239
292
|
// Slack via the winston error transport so a stuck provider or a
|
|
240
293
|
// bad payload always surfaces. Stack tail truncated to keep Slack
|
|
241
294
|
// payloads under their block-size limits.
|
|
295
|
+
// A UserFacingError (render not ready, prompt rejected, …) is an
|
|
296
|
+
// expected outcome the user already sees — warn, don't page. Operator
|
|
297
|
+
// codes (bad key / account out of credit) still page.
|
|
242
298
|
worker.on("failed", (job, err) => {
|
|
243
|
-
|
|
299
|
+
// A non-final attempt will be retried by BullMQ — only the final
|
|
300
|
+
// failure is worth paging on.
|
|
301
|
+
const willRetry = !!job && job.attemptsMade < (job.opts?.attempts ?? 1);
|
|
302
|
+
const logFn = willRetry || (0, errors_1.isQuietUserFacingError)(err) ? logger_1.logger.warn.bind(logger_1.logger) : logger_1.logger.error.bind(logger_1.logger);
|
|
303
|
+
logFn(`BullMQ job failed`, {
|
|
244
304
|
queueName,
|
|
245
305
|
jobId: job?.id,
|
|
246
306
|
jobName: job?.name,
|
|
247
307
|
userId: job?.data?.userId,
|
|
248
308
|
attemptsMade: job?.attemptsMade,
|
|
309
|
+
willRetry,
|
|
249
310
|
failedReason: job?.failedReason,
|
|
250
311
|
err: err?.stack ?? err?.message ?? String(err),
|
|
251
312
|
});
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
export { translationService } from "./translation.service";
|
|
2
|
-
export { LANGUAGE_DISPLAY_NAMES, buildOutputLanguageSection, isEnglish, languageDisplayName, normalizeLanguageTag, resolveOutputLanguage, } from "./outputLanguage";
|
|
2
|
+
export { LANGUAGE_DISPLAY_NAMES, buildOutputLanguageSection, isEnglish, languageDisplayName, normalizeLanguageTag, resolveOutputLanguage, settleCloseLanguage, } from "./outputLanguage";
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/translation/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EACL,sBAAsB,EACtB,0BAA0B,EAC1B,SAAS,EACT,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/translation/index.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EACL,sBAAsB,EACtB,0BAA0B,EAC1B,SAAS,EACT,mBAAmB,EACnB,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,GACpB,MAAM,kBAAkB,CAAC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.resolveOutputLanguage = exports.normalizeLanguageTag = exports.languageDisplayName = exports.isEnglish = exports.buildOutputLanguageSection = exports.LANGUAGE_DISPLAY_NAMES = exports.translationService = void 0;
|
|
3
|
+
exports.settleCloseLanguage = exports.resolveOutputLanguage = exports.normalizeLanguageTag = exports.languageDisplayName = exports.isEnglish = exports.buildOutputLanguageSection = exports.LANGUAGE_DISPLAY_NAMES = exports.translationService = void 0;
|
|
4
4
|
// Only the new API is exported from the services barrel. The legacy aliases
|
|
5
5
|
// (getTranslationWrapper / detectLang / TRANSLATION_FAILED) are re-exported via
|
|
6
6
|
// utils/helpers instead, so each name reaches the package root through exactly
|
|
@@ -14,3 +14,4 @@ Object.defineProperty(exports, "isEnglish", { enumerable: true, get: function ()
|
|
|
14
14
|
Object.defineProperty(exports, "languageDisplayName", { enumerable: true, get: function () { return outputLanguage_1.languageDisplayName; } });
|
|
15
15
|
Object.defineProperty(exports, "normalizeLanguageTag", { enumerable: true, get: function () { return outputLanguage_1.normalizeLanguageTag; } });
|
|
16
16
|
Object.defineProperty(exports, "resolveOutputLanguage", { enumerable: true, get: function () { return outputLanguage_1.resolveOutputLanguage; } });
|
|
17
|
+
Object.defineProperty(exports, "settleCloseLanguage", { enumerable: true, get: function () { return outputLanguage_1.settleCloseLanguage; } });
|
|
@@ -48,6 +48,15 @@ export declare function normalizeLanguageTag(locale?: string): string | undefine
|
|
|
48
48
|
export declare function languageDisplayName(code: string): string;
|
|
49
49
|
/** True when `code` resolves to English (or is absent). */
|
|
50
50
|
export declare function isEnglish(code?: string): boolean;
|
|
51
|
+
/**
|
|
52
|
+
* Settle a detector verdict that falls in a CLOSE_LANGUAGE_GROUPS cluster.
|
|
53
|
+
* Exported for callers that run the detector themselves, such as
|
|
54
|
+
* /v1/video/generate, which uses the result to pick the spoken language.
|
|
55
|
+
* The UI locale wins when it's in the same cluster (an Indonesian UI plus
|
|
56
|
+
* "Malay" text is Indonesian). Otherwise a constrained LLM pick decides, and
|
|
57
|
+
* the detector's verdict stands if that fails.
|
|
58
|
+
*/
|
|
59
|
+
export declare function settleCloseLanguage(text: string, detected: string, uiTag: string | undefined): Promise<string>;
|
|
51
60
|
/**
|
|
52
61
|
* Decide the output language for a piece of work. See the resolution order in
|
|
53
62
|
* the module docblock.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"outputLanguage.d.ts","sourceRoot":"","sources":["../../../src/services/translation/outputLanguage.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"outputLanguage.d.ts","sourceRoot":"","sources":["../../../src/services/translation/outputLanguage.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AAEH;;;;;;;;;GASG;AACH,eAAO,MAAM,sBAAsB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA0CzD,CAAC;AAEF;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAOxE;AAED,iFAAiF;AACjF,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAIxD;AAED,2DAA2D;AAC3D,wBAAgB,SAAS,CAAC,IAAI,CAAC,EAAE,MAAM,GAAG,OAAO,CAGhD;AAoBD;;;;;;;GAOG;AACH,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,MAAM,EAChB,KAAK,EAAE,MAAM,GAAG,SAAS,GACxB,OAAO,CAAC,MAAM,CAAC,CAyBjB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAClD,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmClB;AAED;;;;;;;GAOG;AACH,wBAAgB,0BAA0B,CACxC,cAAc,EAAE,MAAM,GAAG,SAAS,EAClC,KAAK,EAAE,MAAM,GACZ,MAAM,CAeR"}
|
|
@@ -4,6 +4,7 @@ exports.LANGUAGE_DISPLAY_NAMES = void 0;
|
|
|
4
4
|
exports.normalizeLanguageTag = normalizeLanguageTag;
|
|
5
5
|
exports.languageDisplayName = languageDisplayName;
|
|
6
6
|
exports.isEnglish = isEnglish;
|
|
7
|
+
exports.settleCloseLanguage = settleCloseLanguage;
|
|
7
8
|
exports.resolveOutputLanguage = resolveOutputLanguage;
|
|
8
9
|
exports.buildOutputLanguageSection = buildOutputLanguageSection;
|
|
9
10
|
const types_1 = require("../../globals/types");
|
|
@@ -76,6 +77,8 @@ exports.LANGUAGE_DISPLAY_NAMES = {
|
|
|
76
77
|
ro: "Romanian",
|
|
77
78
|
ru: "Russian",
|
|
78
79
|
sk: "Slovak",
|
|
80
|
+
sr: "Serbian",
|
|
81
|
+
bs: "Bosnian",
|
|
79
82
|
sv: "Swedish",
|
|
80
83
|
th: "Thai",
|
|
81
84
|
tl: "Filipino",
|
|
@@ -117,6 +120,55 @@ function isEnglish(code) {
|
|
|
117
120
|
const tag = normalizeLanguageTag(code);
|
|
118
121
|
return !tag || tag === types_1.ELANGUAGE_CODE.en;
|
|
119
122
|
}
|
|
123
|
+
/**
|
|
124
|
+
* Language pairs the primary detector can't reliably tell apart. Its verdicts
|
|
125
|
+
* here come back `reliable: true` regardless, so the confidence flag doesn't
|
|
126
|
+
* help. A user who writes Indonesian and gets a Malay-narrated video reads it
|
|
127
|
+
* as the product ignoring them (prod complaint 2026-10-10). `hint` lists
|
|
128
|
+
* telltale words so the LLM tie-break has something concrete to go on.
|
|
129
|
+
*/
|
|
130
|
+
const CLOSE_LANGUAGE_GROUPS = [
|
|
131
|
+
{
|
|
132
|
+
codes: ["id", "ms"],
|
|
133
|
+
hint: "Indonesian: tidak/nggak/banget/kalau/bisa/uang/sekolah dasar; " +
|
|
134
|
+
"Malay: tak/nak/sangat/boleh/duit/kanak-kanak/kedai/pasal",
|
|
135
|
+
},
|
|
136
|
+
{ codes: ["hr", "sr", "bs"] },
|
|
137
|
+
{ codes: ["no", "da"] },
|
|
138
|
+
];
|
|
139
|
+
/**
|
|
140
|
+
* Settle a detector verdict that falls in a CLOSE_LANGUAGE_GROUPS cluster.
|
|
141
|
+
* Exported for callers that run the detector themselves, such as
|
|
142
|
+
* /v1/video/generate, which uses the result to pick the spoken language.
|
|
143
|
+
* The UI locale wins when it's in the same cluster (an Indonesian UI plus
|
|
144
|
+
* "Malay" text is Indonesian). Otherwise a constrained LLM pick decides, and
|
|
145
|
+
* the detector's verdict stands if that fails.
|
|
146
|
+
*/
|
|
147
|
+
async function settleCloseLanguage(text, detected, uiTag) {
|
|
148
|
+
const group = CLOSE_LANGUAGE_GROUPS.find((g) => g.codes.includes(detected));
|
|
149
|
+
if (!group)
|
|
150
|
+
return detected;
|
|
151
|
+
if (uiTag && group.codes.includes(uiTag))
|
|
152
|
+
return uiTag;
|
|
153
|
+
try {
|
|
154
|
+
const picked = await translation_service_1.translationService.pickCloseLanguage(text, group.codes.map((code) => ({ code, name: languageDisplayName(code) })), group.hint);
|
|
155
|
+
if (picked !== detected) {
|
|
156
|
+
logger_1.logger.info("outputLanguage: close-language tie-break overrode detector", {
|
|
157
|
+
detected,
|
|
158
|
+
picked,
|
|
159
|
+
uiLocale: uiTag,
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
return picked;
|
|
163
|
+
}
|
|
164
|
+
catch (err) {
|
|
165
|
+
logger_1.logger.warn("outputLanguage: close-language tie-break failed, keeping detector verdict", {
|
|
166
|
+
detected,
|
|
167
|
+
err: err instanceof Error ? err.message : String(err),
|
|
168
|
+
});
|
|
169
|
+
return detected;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
120
172
|
/**
|
|
121
173
|
* Decide the output language for a piece of work. See the resolution order in
|
|
122
174
|
* the module docblock.
|
|
@@ -147,7 +199,7 @@ async function resolveOutputLanguage(params) {
|
|
|
147
199
|
if (detected.reliable && top?.code) {
|
|
148
200
|
const tag = normalizeLanguageTag(top.code);
|
|
149
201
|
if (tag)
|
|
150
|
-
return tag;
|
|
202
|
+
return await settleCloseLanguage(text, tag, uiTag);
|
|
151
203
|
}
|
|
152
204
|
logger_1.logger.info("outputLanguage: detection unreliable, using UI locale", {
|
|
153
205
|
uiLocale: uiTag,
|
|
@@ -57,9 +57,25 @@ declare function translate(text: string, from: ELANGUAGE_CODE, to?: ELANGUAGE_CO
|
|
|
57
57
|
* instead of treating the guess as fact.
|
|
58
58
|
*/
|
|
59
59
|
declare function detectLanguage(text: string): Promise<IDetectLang>;
|
|
60
|
+
/**
|
|
61
|
+
* Choose between closely related languages the primary detector confuses.
|
|
62
|
+
*
|
|
63
|
+
* The primary detector is n-gram based and reliably mislabels casual
|
|
64
|
+
* Indonesian as Malay (measured 2026-10-10: "buat video tentang tips merawat
|
|
65
|
+
* kulit wajah untuk remaja" → ms/98%/reliable:true), and it still marks those
|
|
66
|
+
* verdicts reliable, so the flag can't catch it. An LLM limited to the
|
|
67
|
+
* candidate set separates the pair correctly. Same timeout/retry treatment
|
|
68
|
+
* as callLlmDetect; throws when both attempts fail so the caller can keep
|
|
69
|
+
* the detector's verdict.
|
|
70
|
+
*/
|
|
71
|
+
declare function pickCloseLanguage(text: string, candidates: {
|
|
72
|
+
code: string;
|
|
73
|
+
name: string;
|
|
74
|
+
}[], hint?: string): Promise<string>;
|
|
60
75
|
export declare const translationService: {
|
|
61
76
|
translate: typeof translate;
|
|
62
77
|
detectLanguage: typeof detectLanguage;
|
|
78
|
+
pickCloseLanguage: typeof pickCloseLanguage;
|
|
63
79
|
};
|
|
64
80
|
/** @deprecated use `translationService.translate` */
|
|
65
81
|
export declare const getTranslationWrapper: typeof translate;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"translation.service.d.ts","sourceRoot":"","sources":["../../../src/services/translation/translation.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGlE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAiDvD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAkB,GAAG,MAAM,EAAE,CA8BjF;AA4ID;;;;;;GAMG;AACH,iBAAe,SAAS,CACtB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,cAAc,EACpB,EAAE,GAAE,cAAkC,EACtC,OAAO,GAAE,IAAI,GAAG,IAAW,GAC1B,OAAO,CAAC,MAAM,CAAC,CAiBjB;AA+ID;;;;;;;;;;;;;;GAcG;AACH,iBAAe,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA8ChE;AAOD,eAAO,MAAM,kBAAkB
|
|
1
|
+
{"version":3,"file":"translation.service.d.ts","sourceRoot":"","sources":["../../../src/services/translation/translation.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAGlE;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,eAAO,MAAM,kBAAkB,uBAAuB,CAAC;AAiDvD;;;;GAIG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAkB,GAAG,MAAM,EAAE,CA8BjF;AA4ID;;;;;;GAMG;AACH,iBAAe,SAAS,CACtB,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,cAAc,EACpB,EAAE,GAAE,cAAkC,EACtC,OAAO,GAAE,IAAI,GAAG,IAAW,GAC1B,OAAO,CAAC,MAAM,CAAC,CAiBjB;AA+ID;;;;;;;;;;;;;;GAcG;AACH,iBAAe,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA8ChE;AA8BD;;;;;;;;;;GAUG;AACH,iBAAe,iBAAiB,CAC9B,IAAI,EAAE,MAAM,EACZ,UAAU,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,EAC5C,IAAI,CAAC,EAAE,MAAM,GACZ,OAAO,CAAC,MAAM,CAAC,CAejB;AAOD,eAAO,MAAM,kBAAkB;;;;CAI9B,CAAC;AAGF,qDAAqD;AACrD,eAAO,MAAM,qBAAqB,kBAAY,CAAC;AAC/C,0DAA0D;AAC1D,eAAO,MAAM,UAAU,uBAAiB,CAAC"}
|
|
@@ -462,6 +462,52 @@ async function detectLanguage(text) {
|
|
|
462
462
|
};
|
|
463
463
|
}
|
|
464
464
|
}
|
|
465
|
+
/** One un-retried constrained-choice LLM attempt (see pickCloseLanguage). */
|
|
466
|
+
async function callLlmPickOnce(text, candidates, hint) {
|
|
467
|
+
const service = await loadFallbackService();
|
|
468
|
+
const options = candidates.map((c) => `${c.code} (${c.name})`).join(", ");
|
|
469
|
+
const system = `Identify which of these closely related languages the user's text is ` +
|
|
470
|
+
`written in: ${options}. Decide from vocabulary, spelling and slang` +
|
|
471
|
+
(hint ? ` (${hint})` : "") +
|
|
472
|
+
`. Reply with ONLY the code, nothing else.`;
|
|
473
|
+
const { text: out } = await service.generateText({
|
|
474
|
+
input: [
|
|
475
|
+
{ role: "system", content: system },
|
|
476
|
+
{ role: "user", content: text.slice(0, 1000) },
|
|
477
|
+
],
|
|
478
|
+
modelKey: FALLBACK_MODEL,
|
|
479
|
+
options: { temperature: 0 },
|
|
480
|
+
});
|
|
481
|
+
const code = (out ?? "").trim().toLowerCase().replace(/[^a-z-]/g, "");
|
|
482
|
+
if (!candidates.some((c) => c.code === code)) {
|
|
483
|
+
throw new Error(`LLM language pick returned an off-list reply: "${out}"`);
|
|
484
|
+
}
|
|
485
|
+
return code;
|
|
486
|
+
}
|
|
487
|
+
/**
|
|
488
|
+
* Choose between closely related languages the primary detector confuses.
|
|
489
|
+
*
|
|
490
|
+
* The primary detector is n-gram based and reliably mislabels casual
|
|
491
|
+
* Indonesian as Malay (measured 2026-10-10: "buat video tentang tips merawat
|
|
492
|
+
* kulit wajah untuk remaja" → ms/98%/reliable:true), and it still marks those
|
|
493
|
+
* verdicts reliable, so the flag can't catch it. An LLM limited to the
|
|
494
|
+
* candidate set separates the pair correctly. Same timeout/retry treatment
|
|
495
|
+
* as callLlmDetect; throws when both attempts fail so the caller can keep
|
|
496
|
+
* the detector's verdict.
|
|
497
|
+
*/
|
|
498
|
+
async function pickCloseLanguage(text, candidates, hint) {
|
|
499
|
+
await loadFallbackService(); // outside the timer — see loadFallbackService
|
|
500
|
+
let lastErr;
|
|
501
|
+
for (let attempt = 1; attempt <= FALLBACK_MAX_ATTEMPTS; attempt++) {
|
|
502
|
+
try {
|
|
503
|
+
return await withTimeout(callLlmPickOnce(text, candidates, hint), FALLBACK_ATTEMPT_TIMEOUT_MS, "LLM language pick");
|
|
504
|
+
}
|
|
505
|
+
catch (err) {
|
|
506
|
+
lastErr = err;
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
throw lastErr;
|
|
510
|
+
}
|
|
465
511
|
function errMsg(err) {
|
|
466
512
|
if (err instanceof Error)
|
|
467
513
|
return err.stack ?? err.message;
|
|
@@ -470,6 +516,7 @@ function errMsg(err) {
|
|
|
470
516
|
exports.translationService = {
|
|
471
517
|
translate,
|
|
472
518
|
detectLanguage,
|
|
519
|
+
pickCloseLanguage,
|
|
473
520
|
};
|
|
474
521
|
// ── Legacy aliases (kept so existing callsites need no change) ──────────────
|
|
475
522
|
/** @deprecated use `translationService.translate` */
|
package/lib/utils/errors.d.ts
CHANGED
|
@@ -51,6 +51,13 @@ export type UserFacingErrorCode = keyof typeof USER_FACING_ERROR_CODES;
|
|
|
51
51
|
* the provider's, matching the credit-refund behaviour on failed jobs.
|
|
52
52
|
*/
|
|
53
53
|
export declare const USER_FACING_ERROR_MESSAGES: Record<string, string>;
|
|
54
|
+
/**
|
|
55
|
+
* True for an expected, user-facing failure that should log at warn (Loki)
|
|
56
|
+
* rather than error (Slack): any UserFacingError except the operator-action
|
|
57
|
+
* codes. Duck-typed on `isUserFacingError` so it survives errors crossing a
|
|
58
|
+
* package-copy boundary (functions' npm shared vs the worker's workspace one).
|
|
59
|
+
*/
|
|
60
|
+
export declare function isQuietUserFacingError(err: unknown): boolean;
|
|
54
61
|
/** Friendly default for a code, or undefined if the code is unknown/unset. */
|
|
55
62
|
export declare function friendlyMessageForCode(code: string | undefined): string | undefined;
|
|
56
63
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,iBAAiB,QAAQ;IAClC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;gBAEX,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;IAM1C,qEAAqE;IACrE,MAAM,IAAI;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAG7C;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;IAUlC,wFAAwF;;IAExF,qFAAqF;;IAErF,+FAA+F;;IAE/F,oGAAoG;;IAEpG,gGAAgG;;CAExF,CAAC;AACX,MAAM,MAAM,mBAAmB,GAAG,MAAM,OAAO,uBAAuB,CAAC;AAEvE;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA6B7D,CAAC;
|
|
1
|
+
{"version":3,"file":"errors.d.ts","sourceRoot":"","sources":["../../src/utils/errors.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,qBAAa,eAAgB,SAAQ,KAAK;IACxC,QAAQ,CAAC,iBAAiB,QAAQ;IAClC,QAAQ,CAAC,IAAI,CAAC,EAAE,MAAM,CAAC;gBAEX,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM;IAM1C,qEAAqE;IACrE,MAAM,IAAI;QAAE,IAAI,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE;CAG7C;AAED;;;GAGG;AACH,eAAO,MAAM,uBAAuB;;;;;;;;;;IAUlC,wFAAwF;;IAExF,qFAAqF;;IAErF,+FAA+F;;IAE/F,oGAAoG;;IAEpG,gGAAgG;;CAExF,CAAC;AACX,MAAM,MAAM,mBAAmB,GAAG,MAAM,OAAO,uBAAuB,CAAC;AAEvE;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CA6B7D,CAAC;AAWF;;;;;GAKG;AACH,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAK5D;AAED,8EAA8E;AAC9E,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAEnF;AAqBD;;;;;;;;;;GAUG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,GAAG,SAAS,EAC3B,IAAI,CAAC,EAAE,MAAM,GACZ,MAAM,CAaR"}
|
package/lib/utils/errors.js
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.USER_FACING_ERROR_MESSAGES = exports.USER_FACING_ERROR_CODES = exports.UserFacingError = void 0;
|
|
4
|
+
exports.isQuietUserFacingError = isQuietUserFacingError;
|
|
4
5
|
exports.friendlyMessageForCode = friendlyMessageForCode;
|
|
5
6
|
exports.sanitizeUserFacingMessage = sanitizeUserFacingMessage;
|
|
6
7
|
/**
|
|
@@ -73,6 +74,28 @@ exports.USER_FACING_ERROR_MESSAGES = {
|
|
|
73
74
|
[exports.USER_FACING_ERROR_CODES.CAPABILITY_MISMATCH]: "This combination of settings isn't supported by the selected model. Please adjust your options and try again.",
|
|
74
75
|
[exports.USER_FACING_ERROR_CODES.SCENES_NOT_READY]: "This video isn't fully generated yet — one or more scenes are still processing. Please wait for generation to finish and try rendering again.",
|
|
75
76
|
};
|
|
77
|
+
/**
|
|
78
|
+
* UserFacingError codes an operator must act on (bad key, account out of
|
|
79
|
+
* credit). These still page even though the user sees a friendly message.
|
|
80
|
+
*/
|
|
81
|
+
const OPERATOR_ACTION_CODES = new Set([
|
|
82
|
+
exports.USER_FACING_ERROR_CODES.PROVIDER_AUTH_ERROR,
|
|
83
|
+
exports.USER_FACING_ERROR_CODES.ACCOUNT_QUOTA_EXCEEDED,
|
|
84
|
+
]);
|
|
85
|
+
/**
|
|
86
|
+
* True for an expected, user-facing failure that should log at warn (Loki)
|
|
87
|
+
* rather than error (Slack): any UserFacingError except the operator-action
|
|
88
|
+
* codes. Duck-typed on `isUserFacingError` so it survives errors crossing a
|
|
89
|
+
* package-copy boundary (functions' npm shared vs the worker's workspace one).
|
|
90
|
+
*/
|
|
91
|
+
function isQuietUserFacingError(err) {
|
|
92
|
+
if (!err || typeof err !== "object")
|
|
93
|
+
return false;
|
|
94
|
+
const e = err;
|
|
95
|
+
if (e.isUserFacingError !== true)
|
|
96
|
+
return false;
|
|
97
|
+
return !(typeof e.code === "string" && OPERATOR_ACTION_CODES.has(e.code));
|
|
98
|
+
}
|
|
76
99
|
/** Friendly default for a code, or undefined if the code is unknown/unset. */
|
|
77
100
|
function friendlyMessageForCode(code) {
|
|
78
101
|
return code ? exports.USER_FACING_ERROR_MESSAGES[code] : undefined;
|