@clipwright/core 0.34.0 → 0.36.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.
Files changed (237) hide show
  1. package/README.md +6 -3
  2. package/dist/account-actors.d.ts +173 -15
  3. package/dist/account-actors.js +142 -11
  4. package/dist/account-actors.js.map +1 -1
  5. package/dist/actor-bounds.d.ts +4 -0
  6. package/dist/actor-bounds.js +4 -0
  7. package/dist/actor-bounds.js.map +1 -1
  8. package/dist/actors.d.ts +31 -0
  9. package/dist/actors.js +26 -0
  10. package/dist/actors.js.map +1 -1
  11. package/dist/api-failure.d.ts +1 -1
  12. package/dist/api-failure.js +2 -2
  13. package/dist/api-failure.js.map +1 -1
  14. package/dist/aspect.d.ts +1 -1
  15. package/dist/aspect.js +5 -5
  16. package/dist/aspect.js.map +1 -1
  17. package/dist/assets.d.ts +30 -6
  18. package/dist/assets.js +26 -8
  19. package/dist/assets.js.map +1 -1
  20. package/dist/billing-terms.d.ts +69 -0
  21. package/dist/billing-terms.js +8 -0
  22. package/dist/billing-terms.js.map +1 -1
  23. package/dist/canvas-fit.js +1 -1
  24. package/dist/canvas-fit.js.map +1 -1
  25. package/dist/contract-dispositions.d.ts +493 -9
  26. package/dist/contract-dispositions.js +38 -14
  27. package/dist/contract-dispositions.js.map +1 -1
  28. package/dist/contracts/v1/workflow-brief.d.ts +1441 -0
  29. package/dist/contracts/v1/workflow-brief.js +4 -0
  30. package/dist/contracts/v1/workflow-brief.js.map +1 -1
  31. package/dist/contracts/v1/workflow-catalog.d.ts +2181 -103
  32. package/dist/contracts/v1/workflow-catalog.js +4 -2
  33. package/dist/contracts/v1/workflow-catalog.js.map +1 -1
  34. package/dist/contracts/v1/workflow-client.d.ts +1673 -3
  35. package/dist/contracts/v1/workflow-client.js +6 -3
  36. package/dist/contracts/v1/workflow-client.js.map +1 -1
  37. package/dist/contracts/v1/workflow-execution.d.ts +164 -12
  38. package/dist/contracts/v1/workflow-execution.js +15 -7
  39. package/dist/contracts/v1/workflow-execution.js.map +1 -1
  40. package/dist/contracts/v1/workflow-plan.d.ts +3228 -140
  41. package/dist/contracts/v1/workflow-primitives.d.ts +3 -1
  42. package/dist/contracts/v1/workflow-primitives.js +1 -1
  43. package/dist/contracts/v1/workflow-primitives.js.map +1 -1
  44. package/dist/contracts/v1/workflow-run-read.d.ts +116 -3
  45. package/dist/edit-billing.d.ts +12 -0
  46. package/dist/edit-billing.js +7 -0
  47. package/dist/edit-billing.js.map +1 -1
  48. package/dist/edit-candidate.d.ts +2 -2
  49. package/dist/edit-candidate.js +2 -2
  50. package/dist/edit-candidate.js.map +1 -1
  51. package/dist/edit-long-form.d.ts +3 -3
  52. package/dist/edit-long-form.js +14 -4
  53. package/dist/edit-long-form.js.map +1 -1
  54. package/dist/edit-revision.d.ts +1 -1
  55. package/dist/edit-revision.js +1 -1
  56. package/dist/edit-revision.js.map +1 -1
  57. package/dist/endpoint-notes.d.ts +3 -0
  58. package/dist/endpoint-notes.js +70 -0
  59. package/dist/endpoint-notes.js.map +1 -0
  60. package/dist/endpoints.d.ts +4 -0
  61. package/dist/endpoints.js +16 -0
  62. package/dist/endpoints.js.map +1 -1
  63. package/dist/errors.d.ts +2 -2
  64. package/dist/errors.js +11 -2
  65. package/dist/errors.js.map +1 -1
  66. package/dist/face-billing.d.ts +55 -0
  67. package/dist/face-billing.js +24 -2
  68. package/dist/face-billing.js.map +1 -1
  69. package/dist/face-delivery.d.ts +1 -1
  70. package/dist/face-delivery.js +1 -1
  71. package/dist/face-delivery.js.map +1 -1
  72. package/dist/faceless-media-record.d.ts +1 -1
  73. package/dist/faceless-media-record.js +1 -1
  74. package/dist/faceless-media-record.js.map +1 -1
  75. package/dist/faceless-price.d.ts +49 -6
  76. package/dist/faceless-price.js +44 -10
  77. package/dist/faceless-price.js.map +1 -1
  78. package/dist/faceless-public-plan.d.ts +6 -2
  79. package/dist/faceless-public-plan.js +11 -7
  80. package/dist/faceless-public-plan.js.map +1 -1
  81. package/dist/faceless-public.d.ts +7 -2
  82. package/dist/faceless-public.js +5 -5
  83. package/dist/faceless-public.js.map +1 -1
  84. package/dist/faceless-voices.d.ts +6 -6
  85. package/dist/faceless-voices.js +5 -5
  86. package/dist/faceless-voices.js.map +1 -1
  87. package/dist/feedback.d.ts +29 -0
  88. package/dist/feedback.js +29 -0
  89. package/dist/feedback.js.map +1 -0
  90. package/dist/generations.d.ts +2 -19
  91. package/dist/generations.js +28 -49
  92. package/dist/generations.js.map +1 -1
  93. package/dist/idempotency.d.ts +2 -0
  94. package/dist/idempotency.js +7 -4
  95. package/dist/idempotency.js.map +1 -1
  96. package/dist/index.d.ts +12 -0
  97. package/dist/index.js +15 -0
  98. package/dist/index.js.map +1 -1
  99. package/dist/long-form-pricing.d.ts +7 -4
  100. package/dist/long-form-pricing.js +13 -10
  101. package/dist/long-form-pricing.js.map +1 -1
  102. package/dist/long-form-revision.js +1 -1
  103. package/dist/long-form-revision.js.map +1 -1
  104. package/dist/media-timebase.js +2 -2
  105. package/dist/media-timebase.js.map +1 -1
  106. package/dist/openapi.d.ts +155 -0
  107. package/dist/openapi.js +339 -0
  108. package/dist/openapi.js.map +1 -0
  109. package/dist/pacing.d.ts +15 -0
  110. package/dist/pacing.js +30 -0
  111. package/dist/pacing.js.map +1 -1
  112. package/dist/parts-pricing.d.ts +84 -0
  113. package/dist/parts-pricing.js +105 -0
  114. package/dist/parts-pricing.js.map +1 -0
  115. package/dist/presenter-beats.d.ts +45 -0
  116. package/dist/presenter-beats.js +144 -0
  117. package/dist/presenter-beats.js.map +1 -0
  118. package/dist/prices.d.ts +98 -0
  119. package/dist/prices.js +193 -0
  120. package/dist/prices.js.map +1 -0
  121. package/dist/public-responses.d.ts +23 -0
  122. package/dist/public-responses.js +11 -0
  123. package/dist/public-responses.js.map +1 -0
  124. package/dist/rate-limit.d.ts +2 -2
  125. package/dist/rate-limit.js +2 -2
  126. package/dist/rate-limit.js.map +1 -1
  127. package/dist/reference-analysis.d.ts +915 -0
  128. package/dist/reference-analysis.js +210 -0
  129. package/dist/reference-analysis.js.map +1 -0
  130. package/dist/reference-kinds.d.ts +8 -0
  131. package/dist/reference-kinds.js +10 -0
  132. package/dist/reference-kinds.js.map +1 -0
  133. package/dist/reference-profile.d.ts +671 -0
  134. package/dist/reference-profile.js +198 -0
  135. package/dist/reference-profile.js.map +1 -0
  136. package/dist/reference-staging.d.ts +583 -0
  137. package/dist/reference-staging.js +153 -0
  138. package/dist/reference-staging.js.map +1 -0
  139. package/dist/reference-voice.d.ts +305 -0
  140. package/dist/reference-voice.js +108 -0
  141. package/dist/reference-voice.js.map +1 -0
  142. package/dist/render-backend.d.ts +1 -1
  143. package/dist/resolved-timeline.d.ts +54 -2
  144. package/dist/resolved-timeline.js +52 -6
  145. package/dist/resolved-timeline.js.map +1 -1
  146. package/dist/run-static-warnings.js +15 -6
  147. package/dist/run-static-warnings.js.map +1 -1
  148. package/dist/runs.d.ts +78 -6
  149. package/dist/runs.js +9 -4
  150. package/dist/runs.js.map +1 -1
  151. package/dist/semantic-inserts.d.ts +1 -1
  152. package/dist/semantic-inserts.js +2 -2
  153. package/dist/semantic-inserts.js.map +1 -1
  154. package/dist/skills.d.ts +1810 -29
  155. package/dist/skills.js +148 -35
  156. package/dist/skills.js.map +1 -1
  157. package/dist/templates/callout.d.ts +2 -2
  158. package/dist/templates/callout.js +6 -6
  159. package/dist/templates/callout.js.map +1 -1
  160. package/dist/templates/checklist.js +2 -2
  161. package/dist/templates/checklist.js.map +1 -1
  162. package/dist/templates/index.d.ts +15 -8
  163. package/dist/templates/index.js +30 -18
  164. package/dist/templates/index.js.map +1 -1
  165. package/dist/templates/notification.js +2 -2
  166. package/dist/templates/notification.js.map +1 -1
  167. package/dist/templates/phone-call.d.ts +3 -0
  168. package/dist/templates/phone-call.js +14 -7
  169. package/dist/templates/phone-call.js.map +1 -1
  170. package/dist/templates/progress.js +2 -2
  171. package/dist/templates/progress.js.map +1 -1
  172. package/dist/templates/size.d.ts +1 -1
  173. package/dist/templates/size.js +1 -1
  174. package/dist/templates/size.js.map +1 -1
  175. package/dist/templates/sounds.d.ts +357 -7
  176. package/dist/templates/sounds.js +34 -12
  177. package/dist/templates/sounds.js.map +1 -1
  178. package/dist/ugc-call.d.ts +89 -0
  179. package/dist/ugc-call.js +111 -0
  180. package/dist/ugc-call.js.map +1 -0
  181. package/dist/ugc-delivery.d.ts +1 -1
  182. package/dist/ugc-delivery.js +1 -1
  183. package/dist/ugc-delivery.js.map +1 -1
  184. package/dist/ugc-framing.d.ts +26 -0
  185. package/dist/ugc-framing.js +64 -0
  186. package/dist/ugc-framing.js.map +1 -0
  187. package/dist/ugc-layers.d.ts +5 -1
  188. package/dist/ugc-layers.js +6 -1
  189. package/dist/ugc-layers.js.map +1 -1
  190. package/dist/ugc-video-media.d.ts +1 -1
  191. package/dist/ugc-video-media.js +1 -1
  192. package/dist/ugc-video-media.js.map +1 -1
  193. package/dist/uploads.d.ts +2 -2
  194. package/dist/uploads.js +2 -2
  195. package/dist/uploads.js.map +1 -1
  196. package/dist/vendor-response.d.ts +4 -0
  197. package/dist/vendor-response.js +12 -0
  198. package/dist/vendor-response.js.map +1 -1
  199. package/dist/voice-admission.d.ts +836 -420
  200. package/dist/voice-admission.js +22 -5
  201. package/dist/voice-admission.js.map +1 -1
  202. package/dist/voice-listing.d.ts +4 -4
  203. package/dist/voice-listing.js +11 -6
  204. package/dist/voice-listing.js.map +1 -1
  205. package/dist/voice-pace.d.ts +34 -0
  206. package/dist/voice-pace.generated.json +72 -0
  207. package/dist/voice-pace.js +34 -0
  208. package/dist/voice-pace.js.map +1 -0
  209. package/dist/voices.d.ts +32 -19
  210. package/dist/voices.js +81 -35
  211. package/dist/voices.js.map +1 -1
  212. package/dist/workflows/catalog.js +2 -1
  213. package/dist/workflows/catalog.js.map +1 -1
  214. package/dist/workflows/index.d.ts +2 -0
  215. package/dist/workflows/index.js +2 -0
  216. package/dist/workflows/index.js.map +1 -1
  217. package/dist/workflows/methods/faceless-explainer.d.ts +388 -10
  218. package/dist/workflows/methods/kinetic-launch.d.ts +388 -10
  219. package/dist/workflows/methods/kinetic-launch.js +1 -1
  220. package/dist/workflows/methods/product-image-story.d.ts +388 -10
  221. package/dist/workflows/methods/reference-remake.d.ts +881 -0
  222. package/dist/workflows/methods/reference-remake.js +26 -0
  223. package/dist/workflows/methods/reference-remake.js.map +1 -0
  224. package/dist/workflows/methods/shared.d.ts +388 -10
  225. package/dist/workflows/methods/shared.js +2 -2
  226. package/dist/workflows/methods/shared.js.map +1 -1
  227. package/dist/workflows/methods/ugc-faq-answer.d.ts +388 -10
  228. package/dist/workflows/methods/ugc-product-intro.d.ts +388 -10
  229. package/dist/workflows/methods/website-proof-demo.d.ts +388 -10
  230. package/dist/workflows/methods/website-proof-demo.js +1 -1
  231. package/dist/workflows/reference-remake.d.ts +684 -0
  232. package/dist/workflows/reference-remake.js +602 -0
  233. package/dist/workflows/reference-remake.js.map +1 -0
  234. package/dist/workflows/validate.js +10 -7
  235. package/dist/workflows/validate.js.map +1 -1
  236. package/package.json +9 -4
  237. package/CHANGELOG.md +0 -1393
@@ -0,0 +1,84 @@
1
+ import { z } from "zod";
2
+ import { type FaceBillingInterval, type PartsFaceTariff, type PresenterEngine } from "./face-billing.js";
3
+ export declare const PARTS_PRICING_VERSION = "parts-v2";
4
+ /** Credits per second a presenter is in the video, covered or not, by the engine that rendered the take. */
5
+ export declare const PRESENTER_CREDITS_PER_SECOND: Readonly<Record<PresenterEngine, number>>;
6
+ /** Voice and render, per second of the finished video. */
7
+ export declare const PRODUCTION_CREDITS_PER_SECOND = 1;
8
+ /** A call scene's live avatar: one HeyGen photo avatar of the still, per still in the delivered video. */
9
+ export declare const LIVE_AVATAR_STILL_CREDITS = 400;
10
+ /** The least a delivered video costs. */
11
+ export declare const DELIVERED_VIDEO_MINIMUM_CREDITS = 50;
12
+ export declare const PRESENTER_ENGINE_LABELS: Readonly<Record<PresenterEngine, string>>;
13
+ /** The long-form run's tariff, frozen at admission like long-form-v1 before it. */
14
+ export declare const PARTS_FACE_TARIFF: PartsFaceTariff;
15
+ /** The face tariffs new runs are admitted on, as a LIST: public text walks it, so another tariff cannot ship silently. */
16
+ export declare const FACE_BILLING_TARIFFS: readonly PartsFaceTariff[];
17
+ /** A short run's tariff: one take, so the presenter is in every second of the video. Its failures keep the short run's outcomes. */
18
+ export declare const durationPartsTariffSchema: z.ZodReadonly<z.ZodObject<{
19
+ version: z.ZodLiteral<1>;
20
+ pricingVersion: z.ZodString;
21
+ presenterCreditsPerSecond: z.ZodReadonly<z.ZodObject<{
22
+ heygen: z.ZodNumber;
23
+ omnihuman: z.ZodNumber;
24
+ }, z.core.$strict>>;
25
+ productionCreditsPerSecond: z.ZodNumber;
26
+ minimumCredits: z.ZodNumber;
27
+ }, z.core.$strict>>;
28
+ export type DurationPartsTariff = z.infer<typeof durationPartsTariffSchema>;
29
+ export declare const PARTS_DURATION_TARIFF: DurationPartsTariff;
30
+ /** One line of an itemized price: what was counted, how many, at what rate, and the product. */
31
+ export declare const partsLineSchema: z.ZodObject<{
32
+ label: z.ZodString;
33
+ unit: z.ZodEnum<{
34
+ face_second: "face_second";
35
+ second: "second";
36
+ still: "still";
37
+ }>;
38
+ quantity: z.ZodNumber;
39
+ unit_credits: z.ZodNumber;
40
+ credits: z.ZodNumber;
41
+ }, z.core.$strict>;
42
+ export type PartsLine = z.infer<typeof partsLineSchema>;
43
+ export interface PartsCharge {
44
+ lines: PartsLine[];
45
+ /** The lines added up, before the minimum. */
46
+ usageCredits: number;
47
+ credits: number;
48
+ minimumApplied: boolean;
49
+ /** Presenter frames over all engines, an overlap counted once. */
50
+ faceFrames: number;
51
+ billableFaceSeconds: number;
52
+ }
53
+ export interface PartsMeasure {
54
+ /** Each engine's presenter intervals: a take's whole slot, covered or not. */
55
+ presenter: Partial<Record<PresenterEngine, readonly FaceBillingInterval[]>>;
56
+ outputFrames: number;
57
+ fps: number;
58
+ liveAvatarStills: number;
59
+ }
60
+ /** A long-form video's price under a parts tariff: each engine's presenter seconds rounded up once over the video, every */
61
+ /** second of the video, each witnessed still; the minimum when delivered. Failure policy is settlement's, not this function's. */
62
+ export declare function calculatePartsCharge(measure: PartsMeasure, tariffInput: PartsFaceTariff, delivered: boolean): PartsCharge;
63
+ /** A short video's price: the presenter is in every second of its one take. Rounding is the legacy rule: whole seconds, at least one. */
64
+ export declare function calculateDurationPartsCharge(durationSec: number, engine: PresenterEngine, tariffInput: DurationPartsTariff, delivered: boolean): PartsCharge;
65
+ /** What a delivered parts-tariff video records about its price. */
66
+ export declare const partsBillingSummarySchema: z.ZodReadonly<z.ZodObject<{
67
+ pricingVersion: z.ZodString;
68
+ lines: z.ZodArray<z.ZodObject<{
69
+ label: z.ZodString;
70
+ unit: z.ZodEnum<{
71
+ face_second: "face_second";
72
+ second: "second";
73
+ still: "still";
74
+ }>;
75
+ quantity: z.ZodNumber;
76
+ unit_credits: z.ZodNumber;
77
+ credits: z.ZodNumber;
78
+ }, z.core.$strict>>;
79
+ minimumCredits: z.ZodNumber;
80
+ minimumApplied: z.ZodBoolean;
81
+ actualDurationSec: z.ZodNumber;
82
+ finalCreditsCharged: z.ZodNumber;
83
+ }, z.core.$strict>>;
84
+ export type PartsBillingSummary = z.infer<typeof partsBillingSummarySchema>;
@@ -0,0 +1,105 @@
1
+ import { z } from "zod";
2
+ import { identifier, partsFaceTariffSchema, presenterRatesSchema, PRESENTER_ENGINES, } from "./face-billing.js";
3
+ import { unionFaceFrames } from "./long-form-pricing.js";
4
+ // Parts prices: one tariff for short and long make_ugc.
5
+ // parts-v2: the HeyGen second 12 → 9; parts-v1, long-form-v1 and 30 a second stay with their snapshots.
6
+ export const PARTS_PRICING_VERSION = "parts-v2";
7
+ /** Credits per second a presenter is in the video, covered or not, by the engine that rendered the take. */
8
+ export const PRESENTER_CREDITS_PER_SECOND = Object.freeze({ heygen: 9, omnihuman: 22 });
9
+ /** Voice and render, per second of the finished video. */
10
+ export const PRODUCTION_CREDITS_PER_SECOND = 1;
11
+ /** A call scene's live avatar: one HeyGen photo avatar of the still, per still in the delivered video. */
12
+ export const LIVE_AVATAR_STILL_CREDITS = 400;
13
+ /** The least a delivered video costs. */
14
+ export const DELIVERED_VIDEO_MINIMUM_CREDITS = 50;
15
+ export const PRESENTER_ENGINE_LABELS = Object.freeze({
16
+ heygen: "presenter, HeyGen Avatar IV", omnihuman: "presenter, OmniHuman 2.0",
17
+ });
18
+ /** The long-form run's tariff, frozen at admission like long-form-v1 before it. */
19
+ export const PARTS_FACE_TARIFF = Object.freeze({
20
+ version: 3, pricingVersion: PARTS_PRICING_VERSION, presenterCreditsPerSecond: PRESENTER_CREDITS_PER_SECOND,
21
+ productionCreditsPerSecond: PRODUCTION_CREDITS_PER_SECOND, liveAvatarStillCredits: LIVE_AVATAR_STILL_CREDITS,
22
+ minimumCredits: DELIVERED_VIDEO_MINIMUM_CREDITS, rounding: "ceil_aggregate_seconds", failurePolicy: "verified_delivery_only",
23
+ });
24
+ /** The face tariffs new runs are admitted on, as a LIST: public text walks it, so another tariff cannot ship silently. */
25
+ export const FACE_BILLING_TARIFFS = Object.freeze([PARTS_FACE_TARIFF]);
26
+ /** A short run's tariff: one take, so the presenter is in every second of the video. Its failures keep the short run's outcomes. */
27
+ export const durationPartsTariffSchema = z.object({
28
+ version: z.literal(1),
29
+ pricingVersion: identifier,
30
+ presenterCreditsPerSecond: presenterRatesSchema,
31
+ productionCreditsPerSecond: z.number().int().nonnegative().max(2_147_483_647),
32
+ minimumCredits: z.number().int().nonnegative().max(2_147_483_647),
33
+ }).strict().readonly();
34
+ export const PARTS_DURATION_TARIFF = Object.freeze({
35
+ version: 1, pricingVersion: PARTS_PRICING_VERSION, presenterCreditsPerSecond: PRESENTER_CREDITS_PER_SECOND,
36
+ productionCreditsPerSecond: PRODUCTION_CREDITS_PER_SECOND, minimumCredits: DELIVERED_VIDEO_MINIMUM_CREDITS,
37
+ });
38
+ /** One line of an itemized price: what was counted, how many, at what rate, and the product. */
39
+ export const partsLineSchema = z.object({
40
+ label: z.string().min(1),
41
+ unit: z.enum(["face_second", "second", "still"]),
42
+ quantity: z.number().int().nonnegative(),
43
+ unit_credits: z.number().int().nonnegative(),
44
+ credits: z.number().int().nonnegative(),
45
+ }).strict();
46
+ const MAX_CREDITS = 2147483647n;
47
+ function settle(lines, minimum, delivered, faceFrames, billableFaceSeconds) {
48
+ const usage = lines.reduce((sum, line) => sum + BigInt(line.credits), 0n);
49
+ // The minimum is per DELIVERED video: a failed run that still bills is charged its parts only.
50
+ const minimumApplied = delivered && usage < BigInt(minimum);
51
+ const credits = minimumApplied ? BigInt(minimum) : usage;
52
+ if (credits > MAX_CREDITS)
53
+ throw new RangeError("parts billing credit overflow");
54
+ return { lines, usageCredits: Number(usage), credits: Number(credits), minimumApplied, faceFrames, billableFaceSeconds };
55
+ }
56
+ function line(label, unit, quantity, unitCredits) {
57
+ const credits = quantity * BigInt(unitCredits);
58
+ if (credits > MAX_CREDITS)
59
+ throw new RangeError("parts billing credit overflow");
60
+ return { label, unit, quantity: Number(quantity), unit_credits: unitCredits, credits: Number(credits) };
61
+ }
62
+ const ceilSeconds = (frames, fps) => (frames + fps - 1n) / fps;
63
+ /** A long-form video's price under a parts tariff: each engine's presenter seconds rounded up once over the video, every */
64
+ /** second of the video, each witnessed still; the minimum when delivered. Failure policy is settlement's, not this function's. */
65
+ export function calculatePartsCharge(measure, tariffInput, delivered) {
66
+ const tariff = partsFaceTariffSchema.parse(tariffInput);
67
+ const fps = BigInt(z.number().int().positive().max(Number.MAX_SAFE_INTEGER).parse(measure.fps));
68
+ const outputFrames = BigInt(z.number().int().positive().max(Number.MAX_SAFE_INTEGER).parse(measure.outputFrames));
69
+ const stills = BigInt(z.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).parse(measure.liveAvatarStills));
70
+ const lines = [];
71
+ let billableFaceSeconds = 0n;
72
+ for (const engine of PRESENTER_ENGINES) {
73
+ const intervals = measure.presenter[engine];
74
+ if (intervals === undefined || intervals.length === 0)
75
+ continue;
76
+ const seconds = ceilSeconds(unionFaceFrames(intervals), fps);
77
+ billableFaceSeconds += seconds;
78
+ lines.push(line(PRESENTER_ENGINE_LABELS[engine], "face_second", seconds, tariff.presenterCreditsPerSecond[engine]));
79
+ }
80
+ lines.push(line("production (voice and render)", "second", ceilSeconds(outputFrames, fps), tariff.productionCreditsPerSecond));
81
+ if (stills > 0n)
82
+ lines.push(line("live avatar on a call", "still", stills, tariff.liveAvatarStillCredits));
83
+ const faceFrames = unionFaceFrames(PRESENTER_ENGINES.flatMap((engine) => [...(measure.presenter[engine] ?? [])]));
84
+ return settle(lines, tariff.minimumCredits, delivered, Number(faceFrames), Number(billableFaceSeconds));
85
+ }
86
+ /** A short video's price: the presenter is in every second of its one take. Rounding is the legacy rule: whole seconds, at least one. */
87
+ export function calculateDurationPartsCharge(durationSec, engine, tariffInput, delivered) {
88
+ const tariff = durationPartsTariffSchema.parse(tariffInput);
89
+ if (!Number.isFinite(durationSec) || durationSec < 0)
90
+ throw new RangeError("duration must be a finite, non-negative number of seconds");
91
+ const seconds = BigInt(Math.max(1, Math.ceil(durationSec)));
92
+ const lines = [line(PRESENTER_ENGINE_LABELS[engine], "face_second", seconds, tariff.presenterCreditsPerSecond[engine]),
93
+ line("production (voice and render)", "second", seconds, tariff.productionCreditsPerSecond)];
94
+ return settle(lines, tariff.minimumCredits, delivered, 0, Number(seconds));
95
+ }
96
+ /** What a delivered parts-tariff video records about its price. */
97
+ export const partsBillingSummarySchema = z.object({
98
+ pricingVersion: identifier,
99
+ lines: z.array(partsLineSchema),
100
+ minimumCredits: z.number().int().nonnegative(),
101
+ minimumApplied: z.boolean(),
102
+ actualDurationSec: z.number().positive().max(Number.MAX_SAFE_INTEGER),
103
+ finalCreditsCharged: z.number().int().nonnegative(),
104
+ }).strict().readonly();
105
+ //# sourceMappingURL=parts-pricing.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parts-pricing.js","sourceRoot":"","sources":["../src/parts-pricing.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,45 @@
1
+ import type { GenerateVideoRequest, GenerationReference } from "./generations.js";
2
+ import type { ReferenceProfile } from "./reference-profile.js";
3
+ import type { UgcInsert, UgcTemplate } from "./skills.js";
4
+ /** Silent presenter beats of a reference (#857 S3): the presenter listens or reacts while the narration goes on. */
5
+ /** A beat is a seedance-2.0 clip whose first frame is the actor portrait, placed as a video insert on its words. */
6
+ export declare const PRESENTER_BEAT_BEHAVIOURS: readonly ["listening", "reacting"];
7
+ export type PresenterBeatBehaviour = (typeof PRESENTER_BEAT_BEHAVIOURS)[number];
8
+ /** The seedance-2.0 row measured live: 720p 9:16, 4–15 s (`GENERATION_CAPABILITIES`). */
9
+ export declare const PRESENTER_BEAT_MODEL = "seedance-2.0";
10
+ export declare const PRESENTER_BEAT_MIN_SEC = 4;
11
+ export declare function presenterBeatPrompt(behaviour: PresenterBeatBehaviour): string;
12
+ /** Long enough for the words at the slowest speech the admission assumes; the insert cuts the rest where its words end. */
13
+ export declare function presenterBeatSeconds(words: number): number;
14
+ export interface PresenterBeat {
15
+ id: string;
16
+ beatIndex: number;
17
+ behaviour: PresenterBeatBehaviour;
18
+ /** Script words as make_ugc counts them; `endWord` is exclusive. */
19
+ startWord: number;
20
+ endWord: number;
21
+ durationS: number;
22
+ prompt: string;
23
+ }
24
+ /** The profile's listening and reacting beats on their script spans, one span per profile beat (null: no words). */
25
+ export declare function planPresenterBeats(input: {
26
+ script: string;
27
+ profile: Pick<ReferenceProfile, "beats">;
28
+ spans: readonly ({
29
+ start: number;
30
+ end: number;
31
+ } | null)[];
32
+ }): {
33
+ beats: PresenterBeat[];
34
+ warnings: string[];
35
+ };
36
+ /** Over-presenter templates that meet a beat move to the free words right before it, else right after, else are dropped and named. */
37
+ /** A full-frame template stays: it is drawn over inserts. */
38
+ export declare function fitTemplatesAroundBeats(script: string, templates: readonly UgcTemplate[], beats: readonly PresenterBeat[]): {
39
+ templates: UgcTemplate[];
40
+ warnings: string[];
41
+ };
42
+ /** The generate_video request of one beat: frame 0 is the actor portrait, so the identity is the portrait's. */
43
+ export declare function presenterBeatGeneration(beat: PresenterBeat, portrait: GenerationReference): GenerateVideoRequest;
44
+ /** The beat as a video insert over the narration: it starts on its first word and ends where its last word ends. */
45
+ export declare function presenterBeatInsert(beat: PresenterBeat, assetId: string): UgcInsert;
@@ -0,0 +1,144 @@
1
+ import { WORDS_PER_SECOND_MIN } from "./pacing.js";
2
+ import { lexicalTokens, quoteOccurrences } from "./semantic-inserts.js";
3
+ import { TEMPLATE_KINDS, templateFieldValues } from "./templates/index.js";
4
+ /** Silent presenter beats of a reference (#857 S3): the presenter listens or reacts while the narration goes on. */
5
+ /** A beat is a seedance-2.0 clip whose first frame is the actor portrait, placed as a video insert on its words. */
6
+ export const PRESENTER_BEAT_BEHAVIOURS = ["listening", "reacting"];
7
+ /** The seedance-2.0 row measured live: 720p 9:16, 4–15 s (`GENERATION_CAPABILITIES`). */
8
+ export const PRESENTER_BEAT_MODEL = "seedance-2.0";
9
+ export const PRESENTER_BEAT_MIN_SEC = 4;
10
+ const PRESENTER_BEAT_MAX_SEC = 15;
11
+ const KEEP = "Same person, same face, hair, clothes, props and room as the first frame. Locked-off camera, vertical UGC video, " +
12
+ "natural light, realistic skin.";
13
+ /** An open-mouth surprise under a voiceover reads as broken lip-sync: every action is asked closed-mouthed. */
14
+ const SILENT = "The person never speaks: the mouth stays closed or in a closed-lip smile the whole time, even when surprised. " +
15
+ "No talking, no lip movement, no captions, no text overlays.";
16
+ const ACTIONS = {
17
+ listening: "The person lifts a smartphone to the ear with one hand and listens silently to a caller, giving a few small nods, " +
18
+ "eyes alive and attentive, brows reacting slightly to what they hear.",
19
+ reacting: "The person glances to the side, the eyebrows rise in quiet closed-mouth surprise, then the face relaxes into a pleased " +
20
+ "closed-lip smile; they look straight at the camera and give a small thumbs-up.",
21
+ };
22
+ export function presenterBeatPrompt(behaviour) {
23
+ return `${KEEP} ${ACTIONS[behaviour]} ${SILENT}`;
24
+ }
25
+ /** Long enough for the words at the slowest speech the admission assumes; the insert cuts the rest where its words end. */
26
+ export function presenterBeatSeconds(words) {
27
+ return Math.min(PRESENTER_BEAT_MAX_SEC, Math.max(PRESENTER_BEAT_MIN_SEC, Math.ceil(words / WORDS_PER_SECOND_MIN)));
28
+ }
29
+ /** The profile's listening and reacting beats on their script spans, one span per profile beat (null: no words). */
30
+ export function planPresenterBeats(input) {
31
+ const words = lexicalTokens(input.script).length;
32
+ if (input.spans.length !== input.profile.beats.length)
33
+ throw new Error("presenter beats need one span per profile beat");
34
+ const beats = [];
35
+ const warnings = [];
36
+ input.profile.beats.forEach((beat, beatIndex) => {
37
+ const behaviour = beat.presenter_behaviour;
38
+ if (!PRESENTER_BEAT_BEHAVIOURS.includes(behaviour))
39
+ return;
40
+ const span = input.spans[beatIndex];
41
+ if (!span) {
42
+ warnings.push(`beat ${beatIndex} (${behaviour}) has no words in the script, so the presenter does not ${behaviour === "listening" ? "listen" : "react"} there`);
43
+ return;
44
+ }
45
+ if (!Number.isSafeInteger(span.start) || !Number.isSafeInteger(span.end) || span.start < 0 || span.end <= span.start || span.end > words) {
46
+ throw new Error(`beat ${beatIndex} span ${span.start}..${span.end} is outside the ${words} script words`);
47
+ }
48
+ const previous = beats.at(-1);
49
+ if (previous && span.start < previous.endWord)
50
+ throw new Error(`beat ${beatIndex} overlaps the beat before it`);
51
+ const count = span.end - span.start;
52
+ if (count / WORDS_PER_SECOND_MIN > PRESENTER_BEAT_MAX_SEC) {
53
+ warnings.push(`beat ${beatIndex} (${behaviour}) may outlast a ${PRESENTER_BEAT_MAX_SEC} s clip; its last frame holds to the end of its words`);
54
+ }
55
+ beats.push({ id: `beat-${beatIndex}`, beatIndex, behaviour: behaviour, startWord: span.start, endWord: span.end,
56
+ durationS: presenterBeatSeconds(count), prompt: presenterBeatPrompt(behaviour) });
57
+ });
58
+ if (beats.length && beats[0].startWord === 0 && beats.at(-1).endWord === words && beats.every((beat, i) => i === 0 || beat.startWord === beats[i - 1].endWord)) {
59
+ throw new Error("presenter beats cover every word and leave the speaking presenter no shot");
60
+ }
61
+ return { beats, warnings };
62
+ }
63
+ /** A beat's insert is a cutaway: an over-presenter template under it would be refused, so it moves next to the beat. */
64
+ const MIN_TEMPLATE_WORDS = 2;
65
+ function templateSpan(tokens, template) {
66
+ const anchor = template.anchor;
67
+ const range = "startWord" in anchor ? anchor : quoteOccurrences(tokens, anchor.quote)[anchor.occurrence ?? 0];
68
+ if (!range)
69
+ return null;
70
+ return { start: range.startWord, end: template.cover_words === undefined ? range.endWord : range.startWord + template.cover_words };
71
+ }
72
+ /** The template moved onto `span`: anchored on those words, its inner quotes spread over them in order. */
73
+ function moved(template, tokens, span) {
74
+ const { cover_words: _cover, ...rest } = template;
75
+ let data = structuredClone(template.data);
76
+ const fields = TEMPLATE_KINDS.find(kind => kind.kind === template.kind)?.quotes ?? [];
77
+ const values = fields.flatMap(field => templateFieldValues(data, field));
78
+ let from = span.start;
79
+ values.forEach(({ path }, index) => {
80
+ const target = Math.max(from, span.start + Math.floor(((index + 0.5) * (span.end - span.start)) / values.length));
81
+ // The shortest phrase from `target` whose first match inside the span, after the previous one, is `target` itself.
82
+ let length = 1;
83
+ while (target + length < span.end && quoteOccurrences(tokens.slice(from, span.end), tokens.slice(target, target + length).join(" "))[0]
84
+ .startWord + from !== target)
85
+ length += 1;
86
+ data = setAt(data, path, tokens.slice(target, target + length).join(" "));
87
+ from = target + length;
88
+ });
89
+ return { ...rest, anchor: { startWord: span.start, endWord: span.end }, data };
90
+ }
91
+ function setAt(data, path, value) {
92
+ const [head, ...tail] = path;
93
+ if (head === undefined)
94
+ return data;
95
+ const copy = Array.isArray(data) ? [...data] : { ...data };
96
+ copy[head] = tail.length ? setAt(data[head], tail, value) : value;
97
+ return copy;
98
+ }
99
+ /** Over-presenter templates that meet a beat move to the free words right before it, else right after, else are dropped and named. */
100
+ /** A full-frame template stays: it is drawn over inserts. */
101
+ export function fitTemplatesAroundBeats(script, templates, beats) {
102
+ const tokens = lexicalTokens(script);
103
+ const spans = templates.map(template => templateSpan(tokens, template));
104
+ const busy = (word, self) => beats.some(beat => word >= beat.startWord && word < beat.endWord) ||
105
+ spans.some((span, index) => index !== self && span !== null && word >= span.start && word < span.end);
106
+ const warnings = [];
107
+ const out = [];
108
+ templates.forEach((template, index) => {
109
+ const span = spans[index];
110
+ const placement = template.placement ?? TEMPLATE_KINDS.find(kind => kind.kind === template.kind)?.placements[0];
111
+ const beat = span && placement !== "full" && beats.find(one => span.start < one.endWord && span.end > one.startWord);
112
+ if (!span || !beat) {
113
+ out.push(template);
114
+ return;
115
+ }
116
+ const want = Math.max(MIN_TEMPLATE_WORDS, span.end - span.start);
117
+ let before = beat.startWord;
118
+ while (before > 0 && beat.startWord - before < want && !busy(before - 1, index))
119
+ before -= 1;
120
+ let after = beat.endWord;
121
+ while (after < tokens.length && after - beat.endWord < want && !busy(after, index))
122
+ after += 1;
123
+ const room = beat.startWord - before >= MIN_TEMPLATE_WORDS ? { start: before, end: beat.startWord }
124
+ : after - beat.endWord >= MIN_TEMPLATE_WORDS ? { start: beat.endWord, end: after } : null;
125
+ if (!room) {
126
+ warnings.push(`template "${template.id}" lies under the ${beat.behaviour} beat and has no free words beside it; it is left out`);
127
+ return;
128
+ }
129
+ spans[index] = room;
130
+ out.push(moved(template, tokens, room));
131
+ warnings.push(`template "${template.id}" moved to the words ${room.end === beat.startWord ? "right before" : "right after"} the ${beat.behaviour} beat, which covers its own`);
132
+ });
133
+ return { templates: out, warnings };
134
+ }
135
+ /** The generate_video request of one beat: frame 0 is the actor portrait, so the identity is the portrait's. */
136
+ export function presenterBeatGeneration(beat, portrait) {
137
+ return { prompt: beat.prompt, model: PRESENTER_BEAT_MODEL, mode: "first_frame", aspect_ratio: "9:16", resolution: "720p",
138
+ duration_s: beat.durationS, first_frame: portrait };
139
+ }
140
+ /** The beat as a video insert over the narration: it starts on its first word and ends where its last word ends. */
141
+ export function presenterBeatInsert(beat, assetId) {
142
+ return { id: beat.id, asset_id: assetId, media_type: "video", anchor: { startWord: beat.startWord, endWord: beat.endWord } };
143
+ }
144
+ //# sourceMappingURL=presenter-beats.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"presenter-beats.js","sourceRoot":"","sources":["../src/presenter-beats.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,98 @@
1
+ import { z } from "zod";
2
+ /** The public price list (#927): every number is read from the constant billing charges by, never typed here. */
3
+ export declare const PRICES_PATH = "/v1/public/prices";
4
+ export declare const PRICE_UNITS: readonly ["call", "second", "face_second", "image", "clip", "clip_second", "still"];
5
+ export type PriceUnit = (typeof PRICE_UNITS)[number];
6
+ /** One part of a price: credits per unit. A price of several parts adds them, then applies the entry's minimum. */
7
+ export declare const priceEntryLine: z.ZodObject<{
8
+ label: z.ZodNullable<z.ZodString>;
9
+ unit: z.ZodEnum<{
10
+ call: "call";
11
+ clip: "clip";
12
+ clip_second: "clip_second";
13
+ face_second: "face_second";
14
+ image: "image";
15
+ second: "second";
16
+ still: "still";
17
+ }>;
18
+ credits: z.ZodNumber;
19
+ }, z.core.$strict>;
20
+ export type PriceEntryLine = z.infer<typeof priceEntryLine>;
21
+ export declare const priceEntry: z.ZodObject<{
22
+ action: z.ZodString;
23
+ tool: z.ZodNullable<z.ZodString>;
24
+ route: z.ZodNullable<z.ZodString>;
25
+ variant: z.ZodNullable<z.ZodString>;
26
+ lines: z.ZodArray<z.ZodObject<{
27
+ label: z.ZodNullable<z.ZodString>;
28
+ unit: z.ZodEnum<{
29
+ call: "call";
30
+ clip: "clip";
31
+ clip_second: "clip_second";
32
+ face_second: "face_second";
33
+ image: "image";
34
+ second: "second";
35
+ still: "still";
36
+ }>;
37
+ credits: z.ZodNumber;
38
+ }, z.core.$strict>>;
39
+ formula: z.ZodNullable<z.ZodString>;
40
+ minimum_credits: z.ZodNullable<z.ZodNumber>;
41
+ quote_tool: z.ZodNullable<z.ZodString>;
42
+ notes: z.ZodNullable<z.ZodString>;
43
+ }, z.core.$strict>;
44
+ export type PriceEntry = z.infer<typeof priceEntry>;
45
+ export declare const pricesResponse: z.ZodObject<{
46
+ prices: z.ZodArray<z.ZodObject<{
47
+ action: z.ZodString;
48
+ tool: z.ZodNullable<z.ZodString>;
49
+ route: z.ZodNullable<z.ZodString>;
50
+ variant: z.ZodNullable<z.ZodString>;
51
+ lines: z.ZodArray<z.ZodObject<{
52
+ label: z.ZodNullable<z.ZodString>;
53
+ unit: z.ZodEnum<{
54
+ call: "call";
55
+ clip: "clip";
56
+ clip_second: "clip_second";
57
+ face_second: "face_second";
58
+ image: "image";
59
+ second: "second";
60
+ still: "still";
61
+ }>;
62
+ credits: z.ZodNumber;
63
+ }, z.core.$strict>>;
64
+ formula: z.ZodNullable<z.ZodString>;
65
+ minimum_credits: z.ZodNullable<z.ZodNumber>;
66
+ quote_tool: z.ZodNullable<z.ZodString>;
67
+ notes: z.ZodNullable<z.ZodString>;
68
+ }, z.core.$strict>>;
69
+ }, z.core.$strict>;
70
+ export type PricesResponse = z.infer<typeof pricesResponse>;
71
+ /** What a client reads: a unit or a field it does not know yet must not break it. */
72
+ export declare const pricesResponseRead: z.ZodObject<{
73
+ prices: z.ZodArray<z.ZodObject<{
74
+ action: z.ZodString;
75
+ tool: z.ZodNullable<z.ZodString>;
76
+ route: z.ZodNullable<z.ZodString>;
77
+ variant: z.ZodNullable<z.ZodString>;
78
+ lines: z.ZodArray<z.ZodObject<{
79
+ label: z.ZodNullable<z.ZodString>;
80
+ unit: z.ZodString;
81
+ credits: z.ZodNumber;
82
+ }, z.core.$loose>>;
83
+ formula: z.ZodNullable<z.ZodString>;
84
+ minimum_credits: z.ZodNullable<z.ZodNumber>;
85
+ quote_tool: z.ZodNullable<z.ZodString>;
86
+ notes: z.ZodNullable<z.ZodString>;
87
+ }, z.core.$loose>>;
88
+ }, z.core.$loose>;
89
+ export type PricesResponseRead = z.infer<typeof pricesResponseRead>;
90
+ /** Whether calling the entry's action may cost credits. */
91
+ export declare const isPaidEntry: (entry: PriceEntry) => boolean;
92
+ export declare const PRICE_LIST: readonly PriceEntry[];
93
+ /** One entry's price in words: its lines added up and its minimum, or its formula. */
94
+ export declare const priceText: (entry: PriceEntry) => string;
95
+ /** The price sentence a billed tool's description ends with; `null` for a free tool. */
96
+ export declare function priceLine(tool: string, list?: readonly PriceEntry[]): string | null;
97
+ /** A billed tool's description with its price line at the end. */
98
+ export declare const withPriceLine: (tool: string, description: string, list?: readonly PriceEntry[]) => string;