@clipwright/core 0.18.0 → 0.20.0
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 +44 -0
- package/dist/__fixtures__/queue-promises.d.ts +5 -84
- package/dist/__fixtures__/queue-promises.js +7 -84
- package/dist/__fixtures__/queue-promises.js.map +1 -1
- package/dist/account-actors.d.ts +25 -25
- package/dist/account-actors.js +25 -25
- package/dist/account-actors.js.map +1 -1
- package/dist/account.d.ts +4 -10
- package/dist/account.js +6 -12
- package/dist/account.js.map +1 -1
- package/dist/actor-bounds.d.ts +4 -4
- package/dist/actor-bounds.js +4 -4
- package/dist/actor-bounds.js.map +1 -1
- package/dist/actor-qualities.d.ts +3 -3
- package/dist/actor-qualities.js +3 -3
- package/dist/actor-qualities.js.map +1 -1
- package/dist/actors.d.ts +8 -8
- package/dist/actors.js +9 -9
- package/dist/actors.js.map +1 -1
- package/dist/api-failure.d.ts +28 -129
- package/dist/api-failure.js +52 -225
- package/dist/api-failure.js.map +1 -1
- package/dist/aspect.d.ts +26 -96
- package/dist/aspect.js +32 -108
- package/dist/aspect.js.map +1 -1
- package/dist/contract-dispositions.d.ts +42 -167
- package/dist/contract-dispositions.js +54 -184
- package/dist/contract-dispositions.js.map +1 -1
- package/dist/endpoints.d.ts +5 -5
- package/dist/endpoints.js +3 -3
- package/dist/endpoints.js.map +1 -1
- package/dist/errors.d.ts +33 -101
- package/dist/errors.js +42 -108
- package/dist/errors.js.map +1 -1
- package/dist/faceless-cut-style.d.ts +115 -0
- package/dist/faceless-cut-style.js +109 -0
- package/dist/faceless-cut-style.js.map +1 -0
- package/dist/faceless-image-qualification.d.ts +97 -0
- package/dist/faceless-image-qualification.js +145 -0
- package/dist/faceless-image-qualification.js.map +1 -0
- package/dist/faceless-short-61.d.ts +83 -0
- package/dist/faceless-short-61.js +152 -0
- package/dist/faceless-short-61.js.map +1 -0
- package/dist/faceless-storyboard-timing.d.ts +40 -0
- package/dist/faceless-storyboard-timing.js +97 -0
- package/dist/faceless-storyboard-timing.js.map +1 -0
- package/dist/faceless-storyboard-v2-plan.d.ts +3 -0
- package/dist/faceless-storyboard-v2-plan.js +112 -0
- package/dist/faceless-storyboard-v2-plan.js.map +1 -0
- package/dist/faceless-storyboard-v2-timing.d.ts +52 -0
- package/dist/faceless-storyboard-v2-timing.js +136 -0
- package/dist/faceless-storyboard-v2-timing.js.map +1 -0
- package/dist/faceless-storyboard-v2.d.ts +44 -0
- package/dist/faceless-storyboard-v2.js +43 -0
- package/dist/faceless-storyboard-v2.js.map +1 -0
- package/dist/faceless-storyboard.d.ts +55 -0
- package/dist/faceless-storyboard.js +105 -0
- package/dist/faceless-storyboard.js.map +1 -0
- package/dist/idempotency.d.ts +8 -44
- package/dist/idempotency.js +10 -44
- package/dist/idempotency.js.map +1 -1
- package/dist/index.js +21 -25
- package/dist/index.js.map +1 -1
- package/dist/long-form-pricing.d.ts +4 -4
- package/dist/long-form-pricing.js +4 -4
- package/dist/long-form-pricing.js.map +1 -1
- package/dist/long-form-profile.d.ts +2 -2
- package/dist/long-form-profile.js +2 -2
- package/dist/long-form-profile.js.map +1 -1
- package/dist/pacing.d.ts +1 -1
- package/dist/pacing.js +1 -1
- package/dist/pacing.js.map +1 -1
- package/dist/public-endpoints.d.ts +9 -11
- package/dist/public-endpoints.js +11 -13
- package/dist/public-endpoints.js.map +1 -1
- package/dist/rate-limit.d.ts +23 -130
- package/dist/rate-limit.js +27 -132
- package/dist/rate-limit.js.map +1 -1
- package/dist/render-backend.d.ts +30 -145
- package/dist/render-backend.js +4 -27
- package/dist/render-backend.js.map +1 -1
- package/dist/run-preflight.d.ts +4 -4
- package/dist/run-preflight.js +10 -10
- package/dist/run-preflight.js.map +1 -1
- package/dist/run-static-warnings.d.ts +8 -8
- package/dist/run-static-warnings.js +24 -24
- package/dist/run-static-warnings.js.map +1 -1
- package/dist/runs.d.ts +18 -55
- package/dist/runs.js +26 -94
- package/dist/runs.js.map +1 -1
- package/dist/script-integrity.d.ts +6 -7
- package/dist/script-integrity.js +7 -8
- package/dist/script-integrity.js.map +1 -1
- package/dist/semantic-inserts.d.ts +4 -4
- package/dist/semantic-inserts.js +6 -6
- package/dist/semantic-inserts.js.map +1 -1
- package/dist/skills.d.ts +33 -107
- package/dist/skills.js +72 -161
- package/dist/skills.js.map +1 -1
- package/dist/tts-backend.d.ts +13 -42
- package/dist/tts-backend.js +2 -10
- package/dist/tts-backend.js.map +1 -1
- package/dist/uploads.d.ts +4 -4
- package/dist/uploads.js +4 -4
- package/dist/uploads.js.map +1 -1
- package/dist/vendor-response.d.ts +17 -80
- package/dist/vendor-response.js +19 -67
- package/dist/vendor-response.js.map +1 -1
- package/dist/voice-admission.d.ts +5 -5
- package/dist/voice-admission.js +6 -6
- package/dist/voice-admission.js.map +1 -1
- package/dist/voice-catalog-data.d.ts +2 -2
- package/dist/voice-catalog-data.js +2 -2
- package/dist/voice-catalog-data.js.map +1 -1
- package/dist/voice-catalog.d.ts +5 -5
- package/dist/voice-catalog.js +6 -6
- package/dist/voice-catalog.js.map +1 -1
- package/dist/voice-listing.d.ts +4 -4
- package/dist/voice-listing.js +6 -6
- package/dist/voice-listing.js.map +1 -1
- package/dist/voices.d.ts +40 -82
- package/dist/voices.js +56 -99
- package/dist/voices.js.map +1 -1
- package/package.json +1 -1
package/dist/aspect.d.ts
CHANGED
|
@@ -1,40 +1,20 @@
|
|
|
1
1
|
import { type AspectRatio, type Resolution } from "./skills.js";
|
|
2
2
|
import type { AspectSource } from "./default-actor.js";
|
|
3
|
-
/**
|
|
4
|
-
* РАЗРЕШЕНИЕ ФОРМАТА ВЫХОДА ПО ЗАПРОСУ И ИСТОЧНИКУ.
|
|
5
|
-
*
|
|
6
|
-
* Решение владельца: МЫ НЕ КРОПАЕМ. Формат берётся от источника, а расхождение
|
|
7
|
-
* с запрошенным не подменяется молча — оно либо объявляется предупреждением,
|
|
8
|
-
* либо отклоняется до платного вызова (правило проекта №3, переписанное
|
|
9
|
-
* правило №4).
|
|
10
|
-
*
|
|
11
|
-
* Чистые функции, ноль сети: проба источника живёт в воркере, сюда приходит
|
|
12
|
-
* уже измеренная пара сторон.
|
|
13
|
-
*/
|
|
14
|
-
/** Числовое отношение ширины к высоте для каждого поддерживаемого формата. */
|
|
3
|
+
/** Width-to-height ratio of each supported format. */
|
|
15
4
|
export declare const ASPECT_RATIO_VALUES: Record<AspectRatio, number>;
|
|
16
|
-
/**
|
|
17
|
-
|
|
18
|
-
* «клиент попросил 9:16» и «клиент промолчал» можно только так, а на этом
|
|
19
|
-
* различии стоит вся двухслойная развилка (промолчал → снап с предупреждением;
|
|
20
|
-
* попросил явно → возможен fail-closed).
|
|
21
|
-
*/
|
|
5
|
+
/** Default format. A constant, not a schema `.default()`, so "asked for 9:16" stays */
|
|
6
|
+
/** distinguishable from "said nothing": only the latter never gets a refusal. */
|
|
22
7
|
export declare const DEFAULT_ASPECT_RATIO: AspectRatio;
|
|
23
|
-
/** ≤2%
|
|
8
|
+
/** ≤2% counts as a match: the difference is invisible and needs no crop. */
|
|
24
9
|
export declare const ASPECT_MATCH_THRESHOLD = 0.02;
|
|
25
|
-
/** ≤15%
|
|
10
|
+
/** ≤15% snaps to a format with a warning about the vendor's center-crop. */
|
|
26
11
|
export declare const ASPECT_SNAP_THRESHOLD = 0.15;
|
|
27
|
-
/**
|
|
28
|
-
|
|
29
|
-
*
|
|
30
|
-
* Делим на МЕНЬШЕЕ из двух намеренно: из двух возможных относительных ошибок
|
|
31
|
-
* берётся бо́льшая, то есть порог срабатывает раньше. Для гарда, который решает,
|
|
32
|
-
* тратить ли деньги, ошибаться следует в сторону «спросить», а не «сделать».
|
|
33
|
-
*/
|
|
12
|
+
/** Relative distance between two aspect ratios, divided by the SMALLER one: the larger */
|
|
13
|
+
/** error trips the threshold earlier, so a spend guard errs toward asking. */
|
|
34
14
|
export declare function aspectDistance(a: number, b: number): number;
|
|
35
|
-
/**
|
|
15
|
+
/** The supported format nearest to an arbitrary ratio. */
|
|
36
16
|
export declare function snapAspect(ratio: number): AspectRatio;
|
|
37
|
-
/**
|
|
17
|
+
/** Resolver verdict: a format with explanations, or a refusal before the paid step. */
|
|
38
18
|
export type AspectResolution = {
|
|
39
19
|
kind: "resolved";
|
|
40
20
|
aspectRatio: AspectRatio;
|
|
@@ -44,90 +24,40 @@ export type AspectResolution = {
|
|
|
44
24
|
message: string;
|
|
45
25
|
};
|
|
46
26
|
export interface ResolveAspectInput {
|
|
47
|
-
/**
|
|
27
|
+
/** What the client asked for; `undefined` means it said nothing. */
|
|
48
28
|
requested: AspectRatio | undefined;
|
|
49
|
-
/**
|
|
50
|
-
|
|
51
|
-
* сделать не удалось. Отсутствие `image` источником не является — там стоит
|
|
52
|
-
* `DEFAULT_ACTOR_SOURCE`.
|
|
53
|
-
*/
|
|
29
|
+
/** The measured source. `null` only when a URL was given but probing failed; */
|
|
30
|
+
/** without `image` the source is `DEFAULT_ACTOR_SOURCE`. */
|
|
54
31
|
source: AspectSource | null;
|
|
55
32
|
}
|
|
56
|
-
/**
|
|
57
|
-
|
|
58
|
-
*
|
|
59
|
-
* МОЛЧАЩИЙ КЛИЕНТ НИКОГДА НЕ ПОЛУЧАЕТ ОТКАЗ. Он не делал утверждения, которое
|
|
60
|
-
* можно нарушить, — формат выводится от источника, и любое расхождение
|
|
61
|
-
* объявляется предупреждением. Fail-closed возможен ровно при ЯВНОМ конфликте:
|
|
62
|
-
* клиент назвал формат, а источник от него дальше 15%. Иначе гард превратился бы
|
|
63
|
-
* в стену отказов на выборке из одного-двух пользователей (PM2).
|
|
64
|
-
*/
|
|
33
|
+
/** Which format to render. A silent client is never refused; a refusal happens only when */
|
|
34
|
+
/** the client named a format more than 15% away from the source. */
|
|
65
35
|
export declare function resolveAspectRatio(input: ResolveAspectInput): AspectResolution;
|
|
66
|
-
/**
|
|
67
|
-
|
|
68
|
-
* НОД'ом: 432×768 → `9:16`, 1920×1080 → `16:9`.
|
|
69
|
-
*
|
|
70
|
-
* ЗАЧЕМ отдельно от `snapAspect`: снап отвечает на вопрос «что мы отрендерим»
|
|
71
|
-
* и обязан вернуть одно из поддерживаемых значений, а эта функция отвечает на
|
|
72
|
-
* вопрос «что вы прислали». Подставь мы сюда снап, источник 16:9 отчитался бы
|
|
73
|
-
* как `1:1` — то есть quote соврал бы про вход агента ровно в том месте, где он
|
|
74
|
-
* должен помочь агенту понять расхождение.
|
|
75
|
-
*/
|
|
36
|
+
/** Exact source ratio label, reduced by GCD: 432×768 → `9:16`, 1920×1080 → `16:9`. Unlike */
|
|
37
|
+
/** `snapAspect` (what we render), this reports what was sent, so a quote never misstates input. */
|
|
76
38
|
export declare function exactAspectLabel(width: number, height: number): string;
|
|
77
|
-
/**
|
|
78
|
-
|
|
79
|
-
* клиентом (US-527).
|
|
80
|
-
*
|
|
81
|
-
* ЗАЧЕМ ТАК. Живое измерение US-530 показало: вендор портит кадр ровно тогда,
|
|
82
|
-
* когда просимый формат расходится с источником, — в одну сторону режет бока,
|
|
83
|
-
* в другую добивает белым. Значит единственная точка, где кадр не страдает, —
|
|
84
|
-
* совпадение с источником. Просим её, а нужный клиенту кадр собираем сами:
|
|
85
|
-
* укладка на нашей стороне объявляется в `warnings[]`, вендорская — нет.
|
|
86
|
-
*
|
|
87
|
-
* ПОЧЕМУ НЕ «ВСЕГДА КВАДРАТ». Соблазн просить `1:1` всегда (он единственный,
|
|
88
|
-
* где измерение дало нетронутый кадр) неверен: квадрат был нетронут ДЛЯ
|
|
89
|
-
* КВАДРАТНОГО источника. Дефолтный актёр — 432×768, и запрос `1:1` срезал бы
|
|
90
|
-
* ему бока на каждом дефолтном ране. Свойство принадлежит совпадению, а не
|
|
91
|
-
* квадрату.
|
|
92
|
-
*/
|
|
39
|
+
/** The format we ask the VENDOR for is the one nearest the SOURCE, not the requested one: */
|
|
40
|
+
/** the vendor damages the frame only on a mismatch, and our own layout is declared in warnings. */
|
|
93
41
|
export declare function vendorAspectFor(source: AspectSource, supported: readonly AspectRatio[]): AspectRatio;
|
|
94
|
-
/**
|
|
42
|
+
/** What we predicted and what the vendor actually delivered. */
|
|
95
43
|
export interface DeliveredClip {
|
|
96
44
|
width: number;
|
|
97
45
|
height: number;
|
|
98
46
|
durationSec: number;
|
|
99
47
|
}
|
|
100
|
-
/**
|
|
101
|
-
|
|
102
|
-
*
|
|
103
|
-
* ЗАЧЕМ. Все наши правила о поведении вендора — пороги, тексты отказов, выбор
|
|
104
|
-
* формата — выведены из ОДНОГО дня измерений на ОДНОМ квадратном источнике
|
|
105
|
-
* (US-530). Это снимок чужого эндпоинта: он может поменять поля, частоту
|
|
106
|
-
* кадров или добивку длительности молча, и каждое выведенное правило продолжит
|
|
107
|
-
* утверждать вчерашнее с полной уверенностью. Сверка превращает каждый
|
|
108
|
-
* оплаченный ран в бесплатный перезамер — и ловит расхождение в тот день,
|
|
109
|
-
* когда оно появилось, а не в тот, когда на него пожаловался клиент.
|
|
110
|
-
*
|
|
111
|
-
* МОЛЧАНИЕ ПРИ СОВПАДЕНИИ ОБЯЗАТЕЛЬНО. Предупреждение на каждом ране
|
|
112
|
-
* обесценивает предупреждения вообще.
|
|
113
|
-
*/
|
|
48
|
+
/** Compares vendor output with the prediction, so every paid run re-measures vendor */
|
|
49
|
+
/** behavior. Silent on a match: a warning on every run devalues all warnings. */
|
|
114
50
|
export declare function deliveryWarnings(args: {
|
|
115
51
|
predicted: DeliveredClip;
|
|
116
52
|
actual: DeliveredClip;
|
|
117
|
-
/**
|
|
53
|
+
/** Duration tolerance: the vendor rounds, and fractions of a second are not a mismatch. */
|
|
118
54
|
durationToleranceSec?: number;
|
|
119
55
|
}): string[];
|
|
120
|
-
/**
|
|
121
|
-
/**
|
|
56
|
+
/** Upscaling is named, like a format snap, but only for a FOREIGN frame: our actor's */
|
|
57
|
+
/** dimensions are a product property. */
|
|
122
58
|
export declare function upscaleWarning(source: AspectSource | null, resolution: Resolution, aspectRatio: AspectRatio): string | null;
|
|
123
|
-
/**
|
|
124
|
-
|
|
125
|
-
*
|
|
126
|
-
* Первая редакция сверки предсказывала кадр только по формату и потому
|
|
127
|
-
* объявляла расхождением каждый ран в 720p — то есть каждый dev-ран, где
|
|
128
|
-
* дефолтное разрешение понижено. Предупреждение, срабатывающее там, где всё
|
|
129
|
-
* сошлось, обесценивает предупреждения вообще; проверка это поймала.
|
|
130
|
-
*/
|
|
59
|
+
/** The frame we expect from the vendor: format PLUS resolution. Format alone flagged */
|
|
60
|
+
/** every 720p run as a mismatch. */
|
|
131
61
|
export declare function expectedVendorFrame(resolution: Resolution, aspectRatio: AspectRatio): {
|
|
132
62
|
width: number;
|
|
133
63
|
height: number;
|
package/dist/aspect.js
CHANGED
|
@@ -1,43 +1,25 @@
|
|
|
1
1
|
import { ASPECT_RATIOS } from "./skills.js";
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
* Решение владельца: МЫ НЕ КРОПАЕМ. Формат берётся от источника, а расхождение
|
|
6
|
-
* с запрошенным не подменяется молча — оно либо объявляется предупреждением,
|
|
7
|
-
* либо отклоняется до платного вызова (правило проекта №3, переписанное
|
|
8
|
-
* правило №4).
|
|
9
|
-
*
|
|
10
|
-
* Чистые функции, ноль сети: проба источника живёт в воркере, сюда приходит
|
|
11
|
-
* уже измеренная пара сторон.
|
|
12
|
-
*/
|
|
13
|
-
/** Числовое отношение ширины к высоте для каждого поддерживаемого формата. */
|
|
2
|
+
// Output format from the request and the source. We never crop: a mismatch is either
|
|
3
|
+
// a warning or a refusal before the paid call. Pure functions; probing lives in the worker.
|
|
4
|
+
/** Width-to-height ratio of each supported format. */
|
|
14
5
|
export const ASPECT_RATIO_VALUES = {
|
|
15
6
|
"9:16": 9 / 16,
|
|
16
7
|
"1:1": 1,
|
|
17
8
|
"16:9": 16 / 9,
|
|
18
9
|
};
|
|
19
|
-
/**
|
|
20
|
-
|
|
21
|
-
* «клиент попросил 9:16» и «клиент промолчал» можно только так, а на этом
|
|
22
|
-
* различии стоит вся двухслойная развилка (промолчал → снап с предупреждением;
|
|
23
|
-
* попросил явно → возможен fail-closed).
|
|
24
|
-
*/
|
|
10
|
+
/** Default format. A constant, not a schema `.default()`, so "asked for 9:16" stays */
|
|
11
|
+
/** distinguishable from "said nothing": only the latter never gets a refusal. */
|
|
25
12
|
export const DEFAULT_ASPECT_RATIO = "9:16";
|
|
26
|
-
/** ≤2%
|
|
13
|
+
/** ≤2% counts as a match: the difference is invisible and needs no crop. */
|
|
27
14
|
export const ASPECT_MATCH_THRESHOLD = 0.02;
|
|
28
|
-
/** ≤15%
|
|
15
|
+
/** ≤15% snaps to a format with a warning about the vendor's center-crop. */
|
|
29
16
|
export const ASPECT_SNAP_THRESHOLD = 0.15;
|
|
30
|
-
/**
|
|
31
|
-
|
|
32
|
-
*
|
|
33
|
-
* Делим на МЕНЬШЕЕ из двух намеренно: из двух возможных относительных ошибок
|
|
34
|
-
* берётся бо́льшая, то есть порог срабатывает раньше. Для гарда, который решает,
|
|
35
|
-
* тратить ли деньги, ошибаться следует в сторону «спросить», а не «сделать».
|
|
36
|
-
*/
|
|
17
|
+
/** Relative distance between two aspect ratios, divided by the SMALLER one: the larger */
|
|
18
|
+
/** error trips the threshold earlier, so a spend guard errs toward asking. */
|
|
37
19
|
export function aspectDistance(a, b) {
|
|
38
20
|
return Math.abs(a - b) / Math.min(a, b);
|
|
39
21
|
}
|
|
40
|
-
/**
|
|
22
|
+
/** The supported format nearest to an arbitrary ratio. */
|
|
41
23
|
export function snapAspect(ratio) {
|
|
42
24
|
let best = ASPECT_RATIOS[0];
|
|
43
25
|
let bestDistance = Number.POSITIVE_INFINITY;
|
|
@@ -50,21 +32,13 @@ export function snapAspect(ratio) {
|
|
|
50
32
|
}
|
|
51
33
|
return best;
|
|
52
34
|
}
|
|
53
|
-
/**
|
|
54
|
-
|
|
55
|
-
*
|
|
56
|
-
* МОЛЧАЩИЙ КЛИЕНТ НИКОГДА НЕ ПОЛУЧАЕТ ОТКАЗ. Он не делал утверждения, которое
|
|
57
|
-
* можно нарушить, — формат выводится от источника, и любое расхождение
|
|
58
|
-
* объявляется предупреждением. Fail-closed возможен ровно при ЯВНОМ конфликте:
|
|
59
|
-
* клиент назвал формат, а источник от него дальше 15%. Иначе гард превратился бы
|
|
60
|
-
* в стену отказов на выборке из одного-двух пользователей (PM2).
|
|
61
|
-
*/
|
|
35
|
+
/** Which format to render. A silent client is never refused; a refusal happens only when */
|
|
36
|
+
/** the client named a format more than 15% away from the source. */
|
|
62
37
|
export function resolveAspectRatio(input) {
|
|
63
38
|
const { requested, source } = input;
|
|
64
39
|
if (source === null) {
|
|
65
|
-
//
|
|
66
|
-
//
|
|
67
|
-
// объявляется предупреждением по образцу RAW_VOICE_ID_VALIDATION_WARNING.
|
|
40
|
+
// Probing the foreign URL failed. That is not a client claim about the format,
|
|
41
|
+
// so the unverified format is a warning, not a refusal.
|
|
68
42
|
return {
|
|
69
43
|
kind: "resolved",
|
|
70
44
|
aspectRatio: requested ?? DEFAULT_ASPECT_RATIO,
|
|
@@ -79,16 +53,8 @@ export function resolveAspectRatio(input) {
|
|
|
79
53
|
if (distance <= ASPECT_MATCH_THRESHOLD) {
|
|
80
54
|
return { kind: "resolved", aspectRatio: target, warnings: [] };
|
|
81
55
|
}
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
// Прежний текст обещал центр-кроп всегда. Живое измерение US-530 (2026-07-22,
|
|
85
|
-
// квадратный источник, четыре формата) показало два разных поведения:
|
|
86
|
-
// кадр ШИРЕ источника — вендор дорисовывает БЕЛЫМ и картинку не трогает
|
|
87
|
-
// (16:9 из квадрата: полосы по 420 px, контент 56% кадра); кадр УЖЕ источника
|
|
88
|
-
// — увеличивает и срезает бока (4:5: ушло ~20% ширины).
|
|
89
|
-
//
|
|
90
|
-
// Предупреждение, называющее не то, что произойдёт, хуже отсутствия
|
|
91
|
-
// предупреждения: клиент готовится к обрезке краёв, а получает белые поля.
|
|
56
|
+
// Measured vendor behavior depends on direction: a frame wider than the source is
|
|
57
|
+
// padded white, a narrower one is scaled up and center-cropped at the sides.
|
|
92
58
|
const targetRatio = ASPECT_RATIO_VALUES[target];
|
|
93
59
|
const snapWarning = targetRatio > sourceRatio
|
|
94
60
|
? `source is ${source.width}×${source.height}; rendering ${target} is wider than the source, ` +
|
|
@@ -98,8 +64,8 @@ export function resolveAspectRatio(input) {
|
|
|
98
64
|
if (distance <= ASPECT_SNAP_THRESHOLD || requested === undefined) {
|
|
99
65
|
return { kind: "resolved", aspectRatio: target, warnings: [snapWarning] };
|
|
100
66
|
}
|
|
101
|
-
//
|
|
102
|
-
//
|
|
67
|
+
// Explicit conflict. The text must name the remedy: for an autonomous agent a
|
|
68
|
+
// refusal without a next step is as bad as a failure.
|
|
103
69
|
const cure = source.origin === "default"
|
|
104
70
|
? `the default actor is ${snapAspect(sourceRatio)} (${source.width}×${source.height}); ` +
|
|
105
71
|
`pass \`image\` with a source close to ${target} to render ${target}`
|
|
@@ -110,16 +76,8 @@ export function resolveAspectRatio(input) {
|
|
|
110
76
|
message: `requested aspect_ratio ${target} conflicts with the source by ${Math.round(distance * 100)}%: ${cure}`,
|
|
111
77
|
};
|
|
112
78
|
}
|
|
113
|
-
/**
|
|
114
|
-
|
|
115
|
-
* НОД'ом: 432×768 → `9:16`, 1920×1080 → `16:9`.
|
|
116
|
-
*
|
|
117
|
-
* ЗАЧЕМ отдельно от `snapAspect`: снап отвечает на вопрос «что мы отрендерим»
|
|
118
|
-
* и обязан вернуть одно из поддерживаемых значений, а эта функция отвечает на
|
|
119
|
-
* вопрос «что вы прислали». Подставь мы сюда снап, источник 16:9 отчитался бы
|
|
120
|
-
* как `1:1` — то есть quote соврал бы про вход агента ровно в том месте, где он
|
|
121
|
-
* должен помочь агенту понять расхождение.
|
|
122
|
-
*/
|
|
79
|
+
/** Exact source ratio label, reduced by GCD: 432×768 → `9:16`, 1920×1080 → `16:9`. Unlike */
|
|
80
|
+
/** `snapAspect` (what we render), this reports what was sent, so a quote never misstates input. */
|
|
123
81
|
export function exactAspectLabel(width, height) {
|
|
124
82
|
const gcd = (a, b) => (b === 0 ? a : gcd(b, a % b));
|
|
125
83
|
const w = Math.round(width);
|
|
@@ -129,22 +87,8 @@ export function exactAspectLabel(width, height) {
|
|
|
129
87
|
const divisor = gcd(w, h);
|
|
130
88
|
return `${w / divisor}:${h / divisor}`;
|
|
131
89
|
}
|
|
132
|
-
/**
|
|
133
|
-
|
|
134
|
-
* клиентом (US-527).
|
|
135
|
-
*
|
|
136
|
-
* ЗАЧЕМ ТАК. Живое измерение US-530 показало: вендор портит кадр ровно тогда,
|
|
137
|
-
* когда просимый формат расходится с источником, — в одну сторону режет бока,
|
|
138
|
-
* в другую добивает белым. Значит единственная точка, где кадр не страдает, —
|
|
139
|
-
* совпадение с источником. Просим её, а нужный клиенту кадр собираем сами:
|
|
140
|
-
* укладка на нашей стороне объявляется в `warnings[]`, вендорская — нет.
|
|
141
|
-
*
|
|
142
|
-
* ПОЧЕМУ НЕ «ВСЕГДА КВАДРАТ». Соблазн просить `1:1` всегда (он единственный,
|
|
143
|
-
* где измерение дало нетронутый кадр) неверен: квадрат был нетронут ДЛЯ
|
|
144
|
-
* КВАДРАТНОГО источника. Дефолтный актёр — 432×768, и запрос `1:1` срезал бы
|
|
145
|
-
* ему бока на каждом дефолтном ране. Свойство принадлежит совпадению, а не
|
|
146
|
-
* квадрату.
|
|
147
|
-
*/
|
|
90
|
+
/** The format we ask the VENDOR for is the one nearest the SOURCE, not the requested one: */
|
|
91
|
+
/** the vendor damages the frame only on a mismatch, and our own layout is declared in warnings. */
|
|
148
92
|
export function vendorAspectFor(source, supported) {
|
|
149
93
|
if (supported.length === 0) {
|
|
150
94
|
throw new Error("vendorAspectFor: backend declares no supported aspect ratios");
|
|
@@ -161,20 +105,8 @@ export function vendorAspectFor(source, supported) {
|
|
|
161
105
|
}
|
|
162
106
|
return best;
|
|
163
107
|
}
|
|
164
|
-
/**
|
|
165
|
-
|
|
166
|
-
*
|
|
167
|
-
* ЗАЧЕМ. Все наши правила о поведении вендора — пороги, тексты отказов, выбор
|
|
168
|
-
* формата — выведены из ОДНОГО дня измерений на ОДНОМ квадратном источнике
|
|
169
|
-
* (US-530). Это снимок чужого эндпоинта: он может поменять поля, частоту
|
|
170
|
-
* кадров или добивку длительности молча, и каждое выведенное правило продолжит
|
|
171
|
-
* утверждать вчерашнее с полной уверенностью. Сверка превращает каждый
|
|
172
|
-
* оплаченный ран в бесплатный перезамер — и ловит расхождение в тот день,
|
|
173
|
-
* когда оно появилось, а не в тот, когда на него пожаловался клиент.
|
|
174
|
-
*
|
|
175
|
-
* МОЛЧАНИЕ ПРИ СОВПАДЕНИИ ОБЯЗАТЕЛЬНО. Предупреждение на каждом ране
|
|
176
|
-
* обесценивает предупреждения вообще.
|
|
177
|
-
*/
|
|
108
|
+
/** Compares vendor output with the prediction, so every paid run re-measures vendor */
|
|
109
|
+
/** behavior. Silent on a match: a warning on every run devalues all warnings. */
|
|
178
110
|
export function deliveryWarnings(args) {
|
|
179
111
|
const { predicted, actual } = args;
|
|
180
112
|
const tolerance = args.durationToleranceSec ?? 0.05;
|
|
@@ -184,19 +116,17 @@ export function deliveryWarnings(args) {
|
|
|
184
116
|
}
|
|
185
117
|
const durationDelta = actual.durationSec - predicted.durationSec;
|
|
186
118
|
if (Math.abs(durationDelta) > tolerance) {
|
|
187
|
-
//
|
|
188
|
-
//
|
|
189
|
-
// общим «длительность разошлась» значило бы прятать известную причину
|
|
190
|
-
// среди неизвестных.
|
|
119
|
+
// Padding to a whole second is a known, measured case (0.6 s of audio came back as
|
|
120
|
+
// 1.0 s) and is named separately from unknown mismatches.
|
|
191
121
|
const paddedToWholeSecond = durationDelta > 0 && Number.isInteger(actual.durationSec) && actual.durationSec <= 1;
|
|
192
122
|
warnings.push(paddedToWholeSecond
|
|
193
|
-
? `vendor padded the clip to ${actual.durationSec}s from ${predicted.durationSec}s of audio` // skill-scope: dynamic —
|
|
123
|
+
? `vendor padded the clip to ${actual.durationSec}s from ${predicted.durationSec}s of audio` // skill-scope: dynamic — warning text, not SQL
|
|
194
124
|
: `vendor returned ${actual.durationSec}s where ${predicted.durationSec}s was expected`);
|
|
195
125
|
}
|
|
196
126
|
return warnings;
|
|
197
127
|
}
|
|
198
|
-
/**
|
|
199
|
-
/**
|
|
128
|
+
/** Upscaling is named, like a format snap, but only for a FOREIGN frame: our actor's */
|
|
129
|
+
/** dimensions are a product property. */
|
|
200
130
|
export function upscaleWarning(source, resolution, aspectRatio) {
|
|
201
131
|
if (source === null || source.origin !== "probed")
|
|
202
132
|
return null;
|
|
@@ -209,20 +139,14 @@ export function upscaleWarning(source, resolution, aspectRatio) {
|
|
|
209
139
|
`the source is upscaled, which softens the picture. Send at least ${frameShort} px ` +
|
|
210
140
|
"on the short side to avoid it.");
|
|
211
141
|
}
|
|
212
|
-
/**
|
|
142
|
+
/** Short frame side per resolution, measured live. */
|
|
213
143
|
const SHORT_SIDE_BY_RESOLUTION = {
|
|
214
144
|
"720p": 720,
|
|
215
145
|
"1080p": 1080,
|
|
216
146
|
"4k": 2160,
|
|
217
147
|
};
|
|
218
|
-
/**
|
|
219
|
-
|
|
220
|
-
*
|
|
221
|
-
* Первая редакция сверки предсказывала кадр только по формату и потому
|
|
222
|
-
* объявляла расхождением каждый ран в 720p — то есть каждый dev-ран, где
|
|
223
|
-
* дефолтное разрешение понижено. Предупреждение, срабатывающее там, где всё
|
|
224
|
-
* сошлось, обесценивает предупреждения вообще; проверка это поймала.
|
|
225
|
-
*/
|
|
148
|
+
/** The frame we expect from the vendor: format PLUS resolution. Format alone flagged */
|
|
149
|
+
/** every 720p run as a mismatch. */
|
|
226
150
|
export function expectedVendorFrame(resolution, aspectRatio) {
|
|
227
151
|
const short = SHORT_SIDE_BY_RESOLUTION[resolution];
|
|
228
152
|
const ratio = ASPECT_RATIO_VALUES[aspectRatio];
|
package/dist/aspect.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"aspect.js","sourceRoot":"","sources":["../src/aspect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAqC,MAAM,aAAa,CAAC;AAI/E
|
|
1
|
+
{"version":3,"file":"aspect.js","sourceRoot":"","sources":["../src/aspect.ts"],"names":[],"mappings":"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"}
|