vidspotai-shared 1.0.122-dev.0 → 1.0.123

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 (35) hide show
  1. package/lib/libs/storage/GcsBackend.d.ts.map +1 -1
  2. package/lib/libs/storage/GcsBackend.js +12 -2
  3. package/lib/libs/storage/cdnUrl.d.ts +12 -0
  4. package/lib/libs/storage/cdnUrl.d.ts.map +1 -1
  5. package/lib/libs/storage/cdnUrl.js +16 -0
  6. package/lib/models/assetPool.model.d.ts +49 -0
  7. package/lib/models/assetPool.model.d.ts.map +1 -1
  8. package/lib/models/assetPool.model.js +41 -0
  9. package/lib/schemas/videoPlan.schema.d.ts +2 -2
  10. package/lib/schemas/videoPlan.schema.d.ts.map +1 -1
  11. package/lib/schemas/videoPlan.schema.js +15 -2
  12. package/lib/services/agent/planner/plannerMessages.d.ts.map +1 -1
  13. package/lib/services/agent/planner/plannerMessages.js +4 -0
  14. package/lib/services/agent/tools/generateScript.tool.d.ts +1 -1
  15. package/lib/services/agent/tools/planVideo.tool.d.ts +1 -1
  16. package/lib/services/aiGen/providers/bytedance/bytedance.service.d.ts.map +1 -1
  17. package/lib/services/aiGen/providers/bytedance/bytedance.service.js +4 -0
  18. package/lib/services/aiGen/providers/google/google.service.d.ts.map +1 -1
  19. package/lib/services/aiGen/providers/google/google.service.js +5 -0
  20. package/lib/services/aiGen/providers/pixverse/pixverse.service.d.ts.map +1 -1
  21. package/lib/services/aiGen/providers/pixverse/pixverse.service.js +6 -1
  22. package/lib/services/assetPool/index.d.ts +2 -0
  23. package/lib/services/assetPool/index.d.ts.map +1 -0
  24. package/lib/services/assetPool/index.js +17 -0
  25. package/lib/services/assetPool/snapshots.service.d.ts +58 -0
  26. package/lib/services/assetPool/snapshots.service.d.ts.map +1 -0
  27. package/lib/services/assetPool/snapshots.service.js +99 -0
  28. package/lib/services/gcp/uploadAudioBuffer.d.ts.map +1 -1
  29. package/lib/services/gcp/uploadAudioBuffer.js +5 -0
  30. package/lib/services/index.d.ts +1 -0
  31. package/lib/services/index.d.ts.map +1 -1
  32. package/lib/services/index.js +1 -0
  33. package/lib/services/translation/translation.service.d.ts.map +1 -1
  34. package/lib/services/translation/translation.service.js +17 -7
  35. package/package.json +1 -1
@@ -1 +1 @@
1
- {"version":3,"file":"GcsBackend.d.ts","sourceRoot":"","sources":["../../../src/libs/storage/GcsBackend.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAMxD,qBAAa,UAAW,YAAW,eAAe;IAChD,QAAQ,CAAC,IAAI,SAAS;IAEhB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpE,aAAa,CACjB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC;IAOZ,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAO3C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGzC"}
1
+ {"version":3,"file":"GcsBackend.d.ts","sourceRoot":"","sources":["../../../src/libs/storage/GcsBackend.ts"],"names":[],"mappings":"AAsBA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,kBAAkB,CAAC;AAMxD,qBAAa,UAAW,YAAW,eAAe;IAChD,QAAQ,CAAC,IAAI,SAAS;IAEhB,KAAK,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIpE,aAAa,CACjB,GAAG,EAAE,MAAM,EACX,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,GAClB,OAAO,CAAC,MAAM,CAAC;IAOZ,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IAO3C,MAAM,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;CAGzC"}
@@ -2,8 +2,18 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.GcsBackend = void 0;
4
4
  /**
5
- * Google Cloud Storage backend — today's system-of-record.
6
- * ========================================================
5
+ * Google Cloud Storage backend — dual role since the R2-primary flip
6
+ * (2026-09-22, MediaStorage.ts §Stage 2).
7
+ * =====================================================================
8
+ *
9
+ * For anything written via `MediaStorage.put`/`putFromFile` (the vast
10
+ * majority of media), this class is used ONLY as `urlMinter` — it mints the
11
+ * signed-URL shape below but never actually stores those bytes; R2 is the
12
+ * sole byte store. For a handful of bespoke pipeline paths that still write
13
+ * real bytes here directly (see MediaStorage.ts's class doc and
14
+ * notes/R2_MEDIA_MIGRATION_PLAN.md §10 for the full list + reasoning), this
15
+ * IS the genuine system-of-record and `MediaStorage.mirrorBytes`/etc. make a
16
+ * best-effort R2 copy afterward.
7
17
  *
8
18
  * Wraps the Firebase Admin bucket. The canonical object path IS the GCS key
9
19
  * (identity mapping). Read URLs are the far-future signed URLs used everywhere
@@ -50,4 +50,16 @@ export declare function toCdnUrl(url: string, opts?: {
50
50
  * there's no local `fetch()` call to wrap.
51
51
  */
52
52
  export declare function fetchOwnMedia(url: string, init?: RequestInit): Promise<Response>;
53
+ /**
54
+ * Permanent public CDN URL for an object `put`/`putFromFile` wrote to R2 —
55
+ * for public content (e.g. the scraped assetPool) that's stored as a final
56
+ * URL rather than rewritten by the frontend's `cdn()` at render time.
57
+ *
58
+ * Always routes through the prod BUCKET token, in every env: the Worker only
59
+ * resolves `/gcs-pub/<that bucket>/`, and R2 keys carry no bucket name, so dev
60
+ * writes land in the same R2 namespace and resolve fine. A dev-bucket-shaped
61
+ * URL (`storage.googleapis.com/vidspot-dev…`) is never rewritten by `cdn()`
62
+ * and 404s against GCS, which no longer holds the bytes.
63
+ */
64
+ export declare function publicCdnUrl(objectPath: string): string;
53
65
  //# sourceMappingURL=cdnUrl.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"cdnUrl.d.ts","sourceRoot":"","sources":["../../../src/libs/storage/cdnUrl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAeH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEnD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CACtB,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,eAAe,CAAA;CAAE,GACtC,MAAM,CAeR;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAEhF"}
1
+ {"version":3,"file":"cdnUrl.d.ts","sourceRoot":"","sources":["../../../src/libs/storage/cdnUrl.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAeH,MAAM,MAAM,eAAe,GAAG,QAAQ,GAAG,SAAS,CAAC;AAEnD;;;;;;;;GAQG;AACH,wBAAgB,QAAQ,CACtB,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE;IAAE,UAAU,CAAC,EAAE,eAAe,CAAA;CAAE,GACtC,MAAM,CAeR;AAED;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,QAAQ,CAAC,CAEhF;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,YAAY,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAGvD"}
@@ -15,6 +15,7 @@
15
15
  Object.defineProperty(exports, "__esModule", { value: true });
16
16
  exports.toCdnUrl = toCdnUrl;
17
17
  exports.fetchOwnMedia = fetchOwnMedia;
18
+ exports.publicCdnUrl = publicCdnUrl;
18
19
  const FIREBASE_STORAGE_HOST = "https://firebasestorage.googleapis.com";
19
20
  const GCS_HOST = "https://storage.googleapis.com";
20
21
  const BUCKET = "vidspot-firebase.firebasestorage.app";
@@ -75,3 +76,18 @@ function toCdnUrl(url, opts) {
75
76
  function fetchOwnMedia(url, init) {
76
77
  return fetch(toCdnUrl(url, { visibility: "private" }), init);
77
78
  }
79
+ /**
80
+ * Permanent public CDN URL for an object `put`/`putFromFile` wrote to R2 —
81
+ * for public content (e.g. the scraped assetPool) that's stored as a final
82
+ * URL rather than rewritten by the frontend's `cdn()` at render time.
83
+ *
84
+ * Always routes through the prod BUCKET token, in every env: the Worker only
85
+ * resolves `/gcs-pub/<that bucket>/`, and R2 keys carry no bucket name, so dev
86
+ * writes land in the same R2 namespace and resolve fine. A dev-bucket-shaped
87
+ * URL (`storage.googleapis.com/vidspot-dev…`) is never rewritten by `cdn()`
88
+ * and 404s against GCS, which no longer holds the bytes.
89
+ */
90
+ function publicCdnUrl(objectPath) {
91
+ const encoded = objectPath.split("/").map(encodeURIComponent).join("/");
92
+ return `${cdnBase()}/gcs-pub/${BUCKET}/${encoded}`;
93
+ }
@@ -33,10 +33,26 @@ export interface IAssetPoolModel {
33
33
  mediaUrl: string;
34
34
  /** Poster still for videos (first-frame JPEG); absent for images. */
35
35
  posterUrl?: string;
36
+ /**
37
+ * 640px-wide WebP (`pool/thumbs/<sha1>.webp`) for grid cards — the image
38
+ * itself, or a video's first frame. Cards load this directly instead of
39
+ * `mediaUrl`: scraped originals run 3–8MB, and pushing dozens of those
40
+ * through next/image at once overran its 7s upstream fetch timeout, so
41
+ * cards rendered as broken images (2026-09-28).
42
+ */
43
+ thumbUrl?: string;
36
44
  /** R2 object key of `mediaUrl`. */
37
45
  r2Key: string;
38
46
  prompt?: string;
39
47
  model?: string;
48
+ /**
49
+ * One of OUR generation model keys (e.g. "kling-avatar"), set only when the
50
+ * item was made with a model we offer — the curated Content Creator clips.
51
+ * `model` is the scraped label and is never used to preselect a model.
52
+ */
53
+ modelKey?: string;
54
+ /** Per-doc override of where Recreate opens; see recreateToolOf(). */
55
+ recreateTool?: TAssetPoolRecreateTool;
40
56
  /** e.g. "higgsfield.ai" / "imagine.art" / "openart.ai". */
41
57
  platform: string;
42
58
  /** tmp/gallery/<source> folder + record id — re-run provenance. */
@@ -45,4 +61,37 @@ export interface IAssetPoolModel {
45
61
  rank: number;
46
62
  createdAt: FieldValue;
47
63
  }
64
+ /** The generation tool a pool card's Recreate opens. */
65
+ export type TAssetPoolRecreateTool = "video" | "image" | "avatar";
66
+ /**
67
+ * Where Recreate sends a pool item, decided here so every surface (gallery,
68
+ * Inspirations tabs, Content Library) routes it the same way. `avatar`-tagged
69
+ * items open the Avatar tool (a portrait becomes the face image); everything
70
+ * else — posters, ads and film stills included — opens the tool for its media
71
+ * type. A doc's own `recreateTool` wins when set, then its `modelKey`.
72
+ */
73
+ export declare function recreateToolOf(a: Pick<IAssetPoolModel, "tags" | "mediaType" | "recreateTool" | "modelKey">): TAssetPoolRecreateTool;
74
+ /** One pool item as `GET /v1/community/pool` returns it (and as the static
75
+ * first-page snapshots store it — both go through toAssetPoolApiItem so the
76
+ * frontend never sees two shapes). */
77
+ export interface IAssetPoolApiItem {
78
+ id: string;
79
+ type: "pool";
80
+ mediaType: IAssetPoolModel["mediaType"];
81
+ mediaUrl: string;
82
+ posterUrl?: string;
83
+ thumbUrl?: string;
84
+ tags: string[];
85
+ orientation: IAssetPoolModel["orientation"];
86
+ width?: number;
87
+ height?: number;
88
+ aspectRatio?: string;
89
+ durationSec?: number;
90
+ prompt?: string;
91
+ model?: string;
92
+ modelKey?: string;
93
+ recreateTool: TAssetPoolRecreateTool;
94
+ platform: string;
95
+ }
96
+ export declare function toAssetPoolApiItem(id: string, a: IAssetPoolModel): IAssetPoolApiItem;
48
97
  //# sourceMappingURL=assetPool.model.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"assetPool.model.d.ts","sourceRoot":"","sources":["../../src/models/assetPool.model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,uHAS1B,CAAC;AACX,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5E;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,SAAS,GAAG,MAAM,CAAC;IAC3B,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC;IAC7B,iEAAiE;IACjE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,WAAW,EAAE,UAAU,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,UAAU,CAAC;CACvB"}
1
+ {"version":3,"file":"assetPool.model.d.ts","sourceRoot":"","sources":["../../src/models/assetPool.model.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,0BAA0B,CAAC;AAEtD;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,uHAS1B,CAAC;AACX,MAAM,MAAM,oBAAoB,GAAG,CAAC,OAAO,uBAAuB,CAAC,CAAC,MAAM,CAAC,CAAC;AAE5E;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,SAAS,GAAG,MAAM,CAAC;IAC3B,SAAS,EAAE,OAAO,GAAG,OAAO,CAAC;IAC7B,iEAAiE;IACjE,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,WAAW,EAAE,UAAU,GAAG,WAAW,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC7D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,oDAAoD;IACpD,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,qEAAqE;IACrE,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;;;;OAMG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,mCAAmC;IACnC,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,YAAY,CAAC,EAAE,sBAAsB,CAAC;IACtC,2DAA2D;IAC3D,QAAQ,EAAE,MAAM,CAAC;IACjB,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;IAClB,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,UAAU,CAAC;CACvB;AAED,wDAAwD;AACxD,MAAM,MAAM,sBAAsB,GAAG,OAAO,GAAG,OAAO,GAAG,QAAQ,CAAC;AAElE;;;;;;GAMG;AACH,wBAAgB,cAAc,CAC5B,CAAC,EAAE,IAAI,CAAC,eAAe,EAAE,MAAM,GAAG,WAAW,GAAG,cAAc,GAAG,UAAU,CAAC,GAC3E,sBAAsB,CAOxB;AAED;;uCAEuC;AACvC,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,eAAe,CAAC,WAAW,CAAC,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,WAAW,EAAE,eAAe,CAAC,aAAa,CAAC,CAAC;IAC5C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,sBAAsB,CAAC;IACrC,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,kBAAkB,CAAC,EAAE,EAAE,MAAM,EAAE,CAAC,EAAE,eAAe,GAAG,iBAAiB,CAoBpF"}
@@ -1,6 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.ASSET_POOL_SURFACE_TAGS = void 0;
4
+ exports.recreateToolOf = recreateToolOf;
5
+ exports.toAssetPoolApiItem = toAssetPoolApiItem;
4
6
  /**
5
7
  * Surface tags — which product surface may pull an asset. One asset can serve
6
8
  * several (a talking-head clip is both `avatar` and `video-inspiration`).
@@ -17,3 +19,42 @@ exports.ASSET_POOL_SURFACE_TAGS = [
17
19
  "film",
18
20
  "content-creator",
19
21
  ];
22
+ /**
23
+ * Where Recreate sends a pool item, decided here so every surface (gallery,
24
+ * Inspirations tabs, Content Library) routes it the same way. `avatar`-tagged
25
+ * items open the Avatar tool (a portrait becomes the face image); everything
26
+ * else — posters, ads and film stills included — opens the tool for its media
27
+ * type. A doc's own `recreateTool` wins when set, then its `modelKey`.
28
+ */
29
+ function recreateToolOf(a) {
30
+ if (a.recreateTool)
31
+ return a.recreateTool;
32
+ // A known model key is authoritative: a Sora clip that merely shows a
33
+ // person (and so got the descriptive `avatar` tag) still recreates in Video.
34
+ if (a.modelKey)
35
+ return a.modelKey.includes("avatar") ? "avatar" : a.mediaType === "video" ? "video" : "image";
36
+ if (a.tags.includes("avatar"))
37
+ return "avatar";
38
+ return a.mediaType === "video" ? "video" : "image";
39
+ }
40
+ function toAssetPoolApiItem(id, a) {
41
+ return {
42
+ id,
43
+ type: "pool",
44
+ mediaType: a.mediaType,
45
+ mediaUrl: a.mediaUrl,
46
+ posterUrl: a.posterUrl,
47
+ thumbUrl: a.thumbUrl,
48
+ tags: a.tags,
49
+ orientation: a.orientation,
50
+ width: a.width,
51
+ height: a.height,
52
+ aspectRatio: a.aspectRatio,
53
+ durationSec: a.durationSec,
54
+ prompt: a.prompt,
55
+ model: a.model,
56
+ modelKey: a.modelKey,
57
+ recreateTool: recreateToolOf(a),
58
+ platform: a.platform,
59
+ };
60
+ }
@@ -485,7 +485,7 @@ export declare const ScriptSchema: z.ZodObject<{
485
485
  fullText: z.ZodString;
486
486
  wordCount: z.ZodOptional<z.ZodNumber>;
487
487
  estimatedDurationMs: z.ZodOptional<z.ZodNumber>;
488
- wpm: z.ZodOptional<z.ZodNumber>;
488
+ wpm: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodOptional<z.ZodNumber>>;
489
489
  }, z.core.$strip>;
490
490
  export type Script = z.infer<typeof ScriptSchema>;
491
491
  export declare const VideoPlanSchema: z.ZodObject<{
@@ -680,7 +680,7 @@ export declare const VideoPlanSchema: z.ZodObject<{
680
680
  fullText: z.ZodString;
681
681
  wordCount: z.ZodOptional<z.ZodNumber>;
682
682
  estimatedDurationMs: z.ZodOptional<z.ZodNumber>;
683
- wpm: z.ZodOptional<z.ZodNumber>;
683
+ wpm: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodOptional<z.ZodNumber>>;
684
684
  }, z.core.$strip>>>;
685
685
  music: z.ZodOptional<z.ZodObject<{
686
686
  strategy: z.ZodEnum<{
@@ -1 +1 @@
1
- {"version":3,"file":"videoPlan.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/videoPlan.schema.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"videoPlan.schema.d.ts","sourceRoot":"","sources":["../../src/schemas/videoPlan.schema.ts"],"names":[],"mappings":"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"}
@@ -451,8 +451,21 @@ exports.ScriptSchema = zod_1.z.object({
451
451
  wordCount: zod_1.z.number().int().nonnegative().optional(),
452
452
  /** Estimated spoken duration in ms at `wpm`. */
453
453
  estimatedDurationMs: zod_1.z.number().nonnegative().optional(),
454
- /** Words-per-minute used for the estimate (typical narration ≈ 150). */
455
- wpm: zod_1.z.number().int().positive().optional(),
454
+ /**
455
+ * Words-per-minute used for the estimate (typical narration ≈ 150).
456
+ *
457
+ * Coercion: the scene-first planner prompt (S1/S2/M1) never mentions this
458
+ * field, yet the LLM occasionally emits a `script` object on a scene-first
459
+ * plan anyway and invents a `wpm` value from nothing — observed in prod as
460
+ * `0`, which fails `positive()` and burns all 3 retries with the same
461
+ * generic duration-shaped correction text, killing the whole project
462
+ * (2026-09-28 incident). Every consumer already falls back with
463
+ * `?? TTS_DEFAULT_WPM` when `wpm` is absent (generateScript/chapterOutline/
464
+ * matchBrollToScript tools), so a non-positive value is strictly worse than
465
+ * no value — drop it at the schema boundary instead of hard-failing.
466
+ */
467
+ wpm: zod_1.z
468
+ .preprocess((v) => (typeof v === "number" && v <= 0 ? undefined : v), zod_1.z.number().int().positive().optional()),
456
469
  });
457
470
  exports.VideoPlanSchema = zod_1.z.object({
458
471
  briefId: zod_1.z.string().optional(),
@@ -1 +1 @@
1
- {"version":3,"file":"plannerMessages.d.ts","sourceRoot":"","sources":["../../../../src/services/agent/planner/plannerMessages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAehF;;;;;GAKG;AAEH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,YAAY,GAAG,SAAS,EACjC,QAAQ,EAAE,cAAc,GAAG,IAAI,EAC/B,WAAW,EAAE,iBAAiB,GAAG,IAAI,EACrC,KAAK,EAAE,gBAAgB,GAAG,IAAI,EAC9B,UAAU,CAAC,EAAE,MAAM,EACnB,eAAe,UAAQ;;;;;;KAsJxB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAiChE"}
1
+ {"version":3,"file":"plannerMessages.d.ts","sourceRoot":"","sources":["../../../../src/services/agent/planner/plannerMessages.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,sCAAsC,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,+BAA+B,CAAC;AAC3D,OAAO,EAAE,gBAAgB,EAAE,MAAM,mCAAmC,CAAC;AACrE,OAAO,EAAE,cAAc,EAAE,iBAAiB,EAAE,MAAM,6BAA6B,CAAC;AAehF;;;;;GAKG;AAEH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,UAAU,EACjB,OAAO,EAAE,YAAY,GAAG,SAAS,EACjC,QAAQ,EAAE,cAAc,GAAG,IAAI,EAC/B,WAAW,EAAE,iBAAiB,GAAG,IAAI,EACrC,KAAK,EAAE,gBAAgB,GAAG,IAAI,EAC9B,UAAU,CAAC,EAAE,MAAM,EACnB,eAAe,UAAQ;;;;;;KA0JxB;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,UAAU,GAAG,OAAO,CAiChE"}
@@ -63,6 +63,10 @@ function buildPlannerMessages(brief, persona, brandKit, styleMemory, bible, last
63
63
  "You are a video-production planner.",
64
64
  "Given a VideoBrief, produce a VideoPlan: an ordered list of scenes",
65
65
  "with per-scene asset strategy, tier, prompt, duration, and voiceover.",
66
+ "Do NOT set the top-level `script` field — it is only used by long-form",
67
+ "script-first authoring and is populated by a separate pipeline step, not",
68
+ "by you. Leave it out entirely; per-scene voiceoverLine is where narration",
69
+ "goes for this plan.",
66
70
  researchSection,
67
71
  "",
68
72
  "Tier rules — respect brief.tierBudget as the maximum tier:",
@@ -167,7 +167,7 @@ declare const OutputSchema: z.ZodObject<{
167
167
  fullText: z.ZodString;
168
168
  wordCount: z.ZodOptional<z.ZodNumber>;
169
169
  estimatedDurationMs: z.ZodOptional<z.ZodNumber>;
170
- wpm: z.ZodOptional<z.ZodNumber>;
170
+ wpm: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodOptional<z.ZodNumber>>;
171
171
  }, z.core.$strip>;
172
172
  suggestedTitle: z.ZodOptional<z.ZodString>;
173
173
  }, z.core.$strip>;
@@ -337,7 +337,7 @@ declare const OutputSchema: z.ZodObject<{
337
337
  fullText: z.ZodString;
338
338
  wordCount: z.ZodOptional<z.ZodNumber>;
339
339
  estimatedDurationMs: z.ZodOptional<z.ZodNumber>;
340
- wpm: z.ZodOptional<z.ZodNumber>;
340
+ wpm: z.ZodPipe<z.ZodTransform<unknown, unknown>, z.ZodOptional<z.ZodNumber>>;
341
341
  }, z.core.$strip>>>;
342
342
  music: z.ZodOptional<z.ZodObject<{
343
343
  strategy: z.ZodEnum<{
@@ -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,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAWlB,qBAAa,gBAAiB,SAAQ,wBAAwB;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CACsD;IAI9E,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,WAAW;IAIb,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA2M3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAiIjD,aAAa,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM;CAyEjD"}
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,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAWlB,qBAAa,gBAAiB,SAAQ,wBAAwB;IAC5D,OAAO,CAAC,QAAQ,CAAC,OAAO,CACsD;IAI9E,OAAO,CAAC,cAAc;IAYtB,OAAO,CAAC,WAAW;IAIb,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA2M3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAqIjD,aAAa,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM;CAyEjD"}
@@ -265,6 +265,10 @@ class ByteDanceService extends baseAiGenProvider_service_1.BaseAiGenProviderServ
265
265
  }
266
266
  const buffer = Buffer.from(await videoResp.arrayBuffer());
267
267
  // ---- Upload to Firebase Storage (PUBLIC URL) ----
268
+ // GCS-PRIMARY (not mediaStorage.put): returns a public
269
+ // firebaseStorageDownloadTokens URL (see publicVideoUrl below), a
270
+ // different shape than mediaStorage.put()'s signed-URL minter produces.
271
+ // See notes/R2_MEDIA_MIGRATION_PLAN.md §10.
268
272
  const filePath = `${outputFilePath}/${outputFilename}.mp4`;
269
273
  const bucket = (0, firebase_1.getBucket)();
270
274
  const file = bucket.file(filePath);
@@ -1 +1 @@
1
- {"version":3,"file":"google.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/google/google.service.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AA+ElB,qBAAa,aAAc,SAAQ,wBAAwB;IAKzD,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAK;;IAQ/C;;;;;;;;;OASG;IACG,YAAY,CAChB,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,oBAAoB,CAAC;IAoChC;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAoCvB;;;;OAIG;YACW,kBAAkB;IAsC1B,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAgU3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAmK3C,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;YAiBnB,cAAc;IAqK5B;;;;;;OAMG;IACH;;;;OAIG;IACG,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAIjC,aAAa,CAAC,EAAE,QAAQ,EAAE,QAAY,EAAE,UAAmB,EAAE,SAAiB,EAAE,SAAa,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,iBAAiB,GAAG,MAAM;CA8BpJ"}
1
+ {"version":3,"file":"google.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/google/google.service.ts"],"names":[],"mappings":"AAkBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AA+ElB,qBAAa,aAAc,SAAQ,wBAAwB;IAKzD,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,OAAO,CAAgB;IAC/B,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAK;;IAQ/C;;;;;;;;;OASG;IACG,YAAY,CAChB,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,oBAAoB,CAAC;IAoChC;;;;;OAKG;IACH,OAAO,CAAC,eAAe;IAoCvB;;;;OAIG;YACW,kBAAkB;IAsC1B,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAgU3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAwK3C,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;YAiBnB,cAAc;IAqK5B;;;;;;OAMG;IACH;;;;OAIG;IACG,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAIjC,aAAa,CAAC,EAAE,QAAQ,EAAE,QAAY,EAAE,UAAmB,EAAE,SAAiB,EAAE,SAAa,EAAE,SAAS,EAAE,WAAW,EAAE,EAAE,iBAAiB,GAAG,MAAM;CA8BpJ"}
@@ -544,6 +544,11 @@ class GoogleService extends baseAiGenProvider_service_1.BaseAiGenProviderService
544
544
  // we only read a fully-written file, (2) a structural ftyp+moov check, and
545
545
  // (3) a stored-vs-local size match after upload. Any failure re-runs the
546
546
  // whole download instead of shipping corruption.
547
+ //
548
+ // GCS-PRIMARY (not mediaStorage.put): the size-verified integrity guard
549
+ // above needs GCS's own writeFromFile + getMetadata size readback: R2
550
+ // gets a best-effort mirror via mediaStorage.mirrorFromFile once the
551
+ // GCS copy is confirmed intact. See notes/R2_MEDIA_MIGRATION_PLAN.md §10.
547
552
  const MAX_FETCH_ATTEMPTS = 3;
548
553
  let uploaded = false;
549
554
  for (let attempt = 1; attempt <= MAX_FETCH_ATTEMPTS && !uploaded; attempt++) {
@@ -1 +1 @@
1
- {"version":3,"file":"pixverse.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/pixverse/pixverse.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAgGlB,qBAAa,eAAgB,SAAQ,wBAAwB;IAC3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkD;IAK1E;;;;;;OAMG;YACW,WAAW;IAkDnB,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAyL3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAoHjD,aAAa,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM;CAkDjD"}
1
+ {"version":3,"file":"pixverse.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/pixverse/pixverse.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAgGlB,qBAAa,eAAgB,SAAQ,wBAAwB;IAC3D,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAkD;IAK1E;;;;;;OAMG;YACW,WAAW;IAkDnB,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAyL3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAyHjD,aAAa,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM;CAkDjD"}
@@ -363,7 +363,12 @@ class PixVerseService extends baseAiGenProvider_service_1.BaseAiGenProviderServi
363
363
  if (durationSec === undefined) {
364
364
  logger_1.logger.warn("PixVerse: could not read delivered duration from the downloaded clip — billing will use the requested duration", { task, bytes: buffer.length });
365
365
  }
366
- // ---- Upload to Firebase ----
366
+ // ---- Upload to Firebase (PUBLIC URL) ----
367
+ // GCS-PRIMARY (not mediaStorage.put): returns a public
368
+ // firebaseStorageDownloadTokens URL (see publicVideoUrl below), a
369
+ // different shape than mediaStorage.put()'s signed-URL minter produces
370
+ // — same reason bytedance.service.ts stays off mediaStorage.put() too.
371
+ // See notes/R2_MEDIA_MIGRATION_PLAN.md §10.
367
372
  const filePath = `${outputFilePath}/${outputFilename}.mp4`;
368
373
  const bucket = (0, firebase_1.getBucket)();
369
374
  const file = bucket.file(filePath);
@@ -0,0 +1,2 @@
1
+ export * from "./snapshots.service";
2
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/services/assetPool/index.ts"],"names":[],"mappings":"AAAA,cAAc,qBAAqB,CAAC"}
@@ -0,0 +1,17 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ __exportStar(require("./snapshots.service"), exports);
@@ -0,0 +1,58 @@
1
+ import { type IAssetPoolApiItem } from "../../models/assetPool.model";
2
+ /**
3
+ * Static, pre-paginated snapshots of the asset pool — what lets every
4
+ * Inspirations tab / gallery render and infinite-scroll with zero per-visitor
5
+ * API calls or Firestore reads. Scraped content changes rarely, so the whole
6
+ * feed is written out as files once per pool change instead of queried per view.
7
+ *
8
+ * pool/snapshots/<projectId>/current.json ← pointer
9
+ * pool/snapshots/<projectId>/<version>/<tag>.<kind>.<page>.json ← { items }
10
+ *
11
+ * The frontend reads current.json + page 0 of each feed at `next build` (baked
12
+ * into the page — see wt-dev-frontend src/lib/poolSnapshot.ts), then fetches
13
+ * page 1, 2, … straight from the CDN as the user scrolls. Page N holds exactly
14
+ * what `GET /v1/community/pool?tag=&mediaType=` would return for that page
15
+ * (same rank order, same toAssetPoolApiItem shape), so the API stays a
16
+ * drop-in fallback.
17
+ *
18
+ * Every write goes to a fresh `<version>` folder, so page files are immutable
19
+ * — exactly what the CDN Worker's 1-year immutable edge cache on gcs-pub
20
+ * assumes. Only current.json is overwritten; readers cache-bust it with a
21
+ * query param (the Worker's edge cache key includes the query string, its R2
22
+ * lookup ignores it). Old versions are deliberately NOT deleted: an already
23
+ * deployed build keeps paging through the version it was built against until
24
+ * the next deploy. They're tiny (a few MB per version).
25
+ *
26
+ * Keyed by Firebase project because dev and prod share one R2 bucket and R2
27
+ * keys carry no bucket name. Regenerate after anything that changes the pool
28
+ * (the loader does it itself; thumbnail backfill / retag: run
29
+ * scripts/writeAssetPoolSnapshots.ts), then redeploy the frontend to bake it.
30
+ */
31
+ export declare const ASSET_POOL_SNAPSHOT_PAGE_SIZE = 24;
32
+ export declare const ASSET_POOL_SNAPSHOT_KINDS: readonly ["all", "image", "video"];
33
+ export type TAssetPoolSnapshotKind = (typeof ASSET_POOL_SNAPSHOT_KINDS)[number];
34
+ export interface IAssetPoolSnapshotManifest {
35
+ version: string;
36
+ generatedAt: string;
37
+ pageSize: number;
38
+ /** Keyed `<tag>.<kind>`. Feeds with no items are omitted. */
39
+ feeds: Record<string, {
40
+ pages: number;
41
+ total: number;
42
+ }>;
43
+ }
44
+ export interface IAssetPoolSnapshotPage {
45
+ items: IAssetPoolApiItem[];
46
+ }
47
+ export declare function assetPoolSnapshotRoot(projectId: string): string;
48
+ export declare function assetPoolSnapshotPageKey(projectId: string, version: string, tag: string, kind: TAssetPoolSnapshotKind, page: number): string;
49
+ /**
50
+ * Writes a complete new snapshot version for `projectId` and flips
51
+ * current.json to it last, so a reader never sees a pointer to a half-written
52
+ * version. Returns the manifest and its public URL.
53
+ */
54
+ export declare function writeAssetPoolSnapshots(projectId: string): Promise<{
55
+ manifest: IAssetPoolSnapshotManifest;
56
+ manifestUrl: string;
57
+ }>;
58
+ //# sourceMappingURL=snapshots.service.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snapshots.service.d.ts","sourceRoot":"","sources":["../../../src/services/assetPool/snapshots.service.ts"],"names":[],"mappings":"AAEA,OAAO,EAGL,KAAK,iBAAiB,EAEvB,MAAM,8BAA8B,CAAC;AAGtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,6BAA6B,KAAK,CAAC;AAChD,eAAO,MAAM,yBAAyB,oCAAqC,CAAC;AAC5E,MAAM,MAAM,sBAAsB,GAAG,CAAC,OAAO,yBAAyB,CAAC,CAAC,MAAM,CAAC,CAAC;AAEhF,MAAM,WAAW,0BAA0B;IACzC,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE,MAAM,CAAC;IACjB,6DAA6D;IAC7D,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACzD;AAED,MAAM,WAAW,sBAAsB;IACrC,KAAK,EAAE,iBAAiB,EAAE,CAAC;CAC5B;AAED,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAE/D;AAED,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,MAAM,EACf,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,sBAAsB,EAC5B,IAAI,EAAE,MAAM,GACX,MAAM,CAER;AAQD;;;;GAIG;AACH,wBAAsB,uBAAuB,CAC3C,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC;IAAE,QAAQ,EAAE,0BAA0B,CAAC;IAAC,WAAW,EAAE,MAAM,CAAA;CAAE,CAAC,CA8CxE"}
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.ASSET_POOL_SNAPSHOT_KINDS = exports.ASSET_POOL_SNAPSHOT_PAGE_SIZE = void 0;
4
+ exports.assetPoolSnapshotRoot = assetPoolSnapshotRoot;
5
+ exports.assetPoolSnapshotPageKey = assetPoolSnapshotPageKey;
6
+ exports.writeAssetPoolSnapshots = writeAssetPoolSnapshots;
7
+ const cdnUrl_1 = require("../../libs/storage/cdnUrl");
8
+ const MediaStorage_1 = require("../../libs/storage/MediaStorage");
9
+ const assetPool_model_1 = require("../../models/assetPool.model");
10
+ const firestore_service_1 = require("../firestore.service");
11
+ /**
12
+ * Static, pre-paginated snapshots of the asset pool — what lets every
13
+ * Inspirations tab / gallery render and infinite-scroll with zero per-visitor
14
+ * API calls or Firestore reads. Scraped content changes rarely, so the whole
15
+ * feed is written out as files once per pool change instead of queried per view.
16
+ *
17
+ * pool/snapshots/<projectId>/current.json ← pointer
18
+ * pool/snapshots/<projectId>/<version>/<tag>.<kind>.<page>.json ← { items }
19
+ *
20
+ * The frontend reads current.json + page 0 of each feed at `next build` (baked
21
+ * into the page — see wt-dev-frontend src/lib/poolSnapshot.ts), then fetches
22
+ * page 1, 2, … straight from the CDN as the user scrolls. Page N holds exactly
23
+ * what `GET /v1/community/pool?tag=&mediaType=` would return for that page
24
+ * (same rank order, same toAssetPoolApiItem shape), so the API stays a
25
+ * drop-in fallback.
26
+ *
27
+ * Every write goes to a fresh `<version>` folder, so page files are immutable
28
+ * — exactly what the CDN Worker's 1-year immutable edge cache on gcs-pub
29
+ * assumes. Only current.json is overwritten; readers cache-bust it with a
30
+ * query param (the Worker's edge cache key includes the query string, its R2
31
+ * lookup ignores it). Old versions are deliberately NOT deleted: an already
32
+ * deployed build keeps paging through the version it was built against until
33
+ * the next deploy. They're tiny (a few MB per version).
34
+ *
35
+ * Keyed by Firebase project because dev and prod share one R2 bucket and R2
36
+ * keys carry no bucket name. Regenerate after anything that changes the pool
37
+ * (the loader does it itself; thumbnail backfill / retag: run
38
+ * scripts/writeAssetPoolSnapshots.ts), then redeploy the frontend to bake it.
39
+ */
40
+ exports.ASSET_POOL_SNAPSHOT_PAGE_SIZE = 24; // = the frontend feed's PAGE_LIMIT
41
+ exports.ASSET_POOL_SNAPSHOT_KINDS = ["all", "image", "video"];
42
+ function assetPoolSnapshotRoot(projectId) {
43
+ return `pool/snapshots/${projectId}`;
44
+ }
45
+ function assetPoolSnapshotPageKey(projectId, version, tag, kind, page) {
46
+ return `${assetPoolSnapshotRoot(projectId)}/${version}/${tag}.${kind}.${page}.json`;
47
+ }
48
+ const WRITE_CONCURRENCY = 16;
49
+ async function putJson(key, value) {
50
+ await MediaStorage_1.mediaStorage.put(key, Buffer.from(JSON.stringify(value)), "application/json");
51
+ }
52
+ /**
53
+ * Writes a complete new snapshot version for `projectId` and flips
54
+ * current.json to it last, so a reader never sees a pointer to a half-written
55
+ * version. Returns the manifest and its public URL.
56
+ */
57
+ async function writeAssetPoolSnapshots(projectId) {
58
+ const generatedAt = new Date().toISOString();
59
+ const version = generatedAt.replace(/[:.]/g, "-");
60
+ const manifest = {
61
+ version,
62
+ generatedAt,
63
+ pageSize: exports.ASSET_POOL_SNAPSHOT_PAGE_SIZE,
64
+ feeds: {},
65
+ };
66
+ const writes = [];
67
+ for (const tag of assetPool_model_1.ASSET_POOL_SURFACE_TAGS) {
68
+ // One read per tag; the per-kind feeds are rank-ordered subsequences of it,
69
+ // identical to what the API's `mediaType ==` + `orderBy rank` query returns.
70
+ const snap = await firestore_service_1.FirestoreService.assetPoolCol.where("tags", "array-contains", tag)
71
+ .orderBy("rank", "asc")
72
+ .get();
73
+ const all = snap.docs.map((d) => (0, assetPool_model_1.toAssetPoolApiItem)(d.id, d.data()));
74
+ for (const kind of exports.ASSET_POOL_SNAPSHOT_KINDS) {
75
+ const items = kind === "all" ? all : all.filter((i) => i.mediaType === kind);
76
+ if (items.length === 0)
77
+ continue;
78
+ const pages = Math.ceil(items.length / exports.ASSET_POOL_SNAPSHOT_PAGE_SIZE);
79
+ manifest.feeds[`${tag}.${kind}`] = { pages, total: items.length };
80
+ for (let p = 0; p < pages; p++) {
81
+ writes.push({
82
+ key: assetPoolSnapshotPageKey(projectId, version, tag, kind, p),
83
+ value: {
84
+ items: items.slice(p * exports.ASSET_POOL_SNAPSHOT_PAGE_SIZE, (p + 1) * exports.ASSET_POOL_SNAPSHOT_PAGE_SIZE),
85
+ },
86
+ });
87
+ }
88
+ }
89
+ }
90
+ let next = 0;
91
+ await Promise.all(Array.from({ length: WRITE_CONCURRENCY }, async () => {
92
+ for (let w = writes[next++]; w; w = writes[next++]) {
93
+ await putJson(w.key, w.value);
94
+ }
95
+ }));
96
+ const manifestKey = `${assetPoolSnapshotRoot(projectId)}/current.json`;
97
+ await putJson(manifestKey, manifest);
98
+ return { manifest, manifestUrl: (0, cdnUrl_1.publicCdnUrl)(manifestKey) };
99
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"uploadAudioBuffer.d.ts","sourceRoot":"","sources":["../../../src/services/gcp/uploadAudioBuffer.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,WAAW,GAAE,MAAqB,GACjC,OAAO,CAAC,MAAM,CAAC,CAcjB"}
1
+ {"version":3,"file":"uploadAudioBuffer.d.ts","sourceRoot":"","sources":["../../../src/services/gcp/uploadAudioBuffer.ts"],"names":[],"mappings":"AAIA;;;;;;;;;;GAUG;AACH,wBAAsB,sBAAsB,CAC1C,MAAM,EAAE,MAAM,EACd,WAAW,EAAE,MAAM,EACnB,WAAW,GAAE,MAAqB,GACjC,OAAO,CAAC,MAAM,CAAC,CAmBjB"}
@@ -16,6 +16,11 @@ const storage_1 = require("../../libs/storage");
16
16
  * are exposed today.
17
17
  */
18
18
  async function uploadAudioBufferToGcs(buffer, destination, contentType = "audio/mpeg") {
19
+ // GCS-PRIMARY (not mediaStorage.put): returns a public
20
+ // firebaseStorageDownloadTokens URL, a different shape than
21
+ // mediaStorage.put()'s signed-URL minter produces — same reason
22
+ // pixverse/bytedance stay off mediaStorage.put() too. See
23
+ // notes/R2_MEDIA_MIGRATION_PLAN.md §10.
19
24
  const bucket = (0, firebase_1.getBucket)();
20
25
  const file = bucket.file(destination);
21
26
  const downloadToken = (0, node_crypto_1.randomUUID)();
@@ -40,4 +40,5 @@ export * from "./socialAccounts";
40
40
  export * from "./freePlan";
41
41
  export * from "./organizationCredit.service";
42
42
  export * from "./email";
43
+ export * from "./assetPool";
43
44
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,OAAO,CAAC;AACtB,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qCAAqC,CAAC;AACpD,cAAc,qBAAqB,CAAC;AACpC,cAAc,OAAO,CAAC;AACtB,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,OAAO,CAAC;AACtB,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,SAAS,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/services/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,eAAe,CAAC;AAC9B,cAAc,qBAAqB,CAAC;AACpC,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC;AAC5B,cAAc,kBAAkB,CAAC;AACjC,cAAc,4BAA4B,CAAC;AAC3C,cAAc,OAAO,CAAC;AACtB,cAAc,kBAAkB,CAAC;AACjC,cAAc,wBAAwB,CAAC;AACvC,cAAc,mBAAmB,CAAC;AAClC,cAAc,qCAAqC,CAAC;AACpD,cAAc,qBAAqB,CAAC;AACpC,cAAc,OAAO,CAAC;AACtB,cAAc,eAAe,CAAC;AAC9B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC;AAC3B,cAAc,iBAAiB,CAAC;AAChC,cAAc,OAAO,CAAC;AACtB,cAAc,SAAS,CAAC;AACxB,cAAc,QAAQ,CAAC;AACvB,cAAc,kBAAkB,CAAC;AACjC,cAAc,sBAAsB,CAAC;AACrC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,0BAA0B,CAAC;AACzC,cAAc,0BAA0B,CAAC;AACzC,cAAc,wBAAwB,CAAC;AACvC,cAAc,2BAA2B,CAAC;AAC1C,cAAc,SAAS,CAAC;AACxB,cAAc,UAAU,CAAC;AACzB,cAAc,eAAe,CAAC;AAC9B,cAAc,iBAAiB,CAAC;AAChC,cAAc,iBAAiB,CAAC;AAChC,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,YAAY,CAAC;AAC3B,cAAc,kBAAkB,CAAC;AACjC,cAAc,kBAAkB,CAAC;AACjC,cAAc,YAAY,CAAC;AAC3B,cAAc,8BAA8B,CAAC;AAC7C,cAAc,SAAS,CAAC;AACxB,cAAc,aAAa,CAAC"}
@@ -56,3 +56,4 @@ __exportStar(require("./socialAccounts"), exports);
56
56
  __exportStar(require("./freePlan"), exports);
57
57
  __exportStar(require("./organizationCredit.service"), exports);
58
58
  __exportStar(require("./email"), exports);
59
+ __exportStar(require("./assetPool"), exports);
@@ -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;AAwIvD;;;;GAIG;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,CAsCjB;AAuDD;;;;;;;;;;;;;;GAcG;AACH,iBAAe,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA8ChE;AAOD,eAAO,MAAM,kBAAkB;;;CAG9B,CAAC;AAGF,qDAAqD;AACrD,eAAO,MAAM,qBAAqB,kBAAY,CAAC;AAC/C,0DAA0D;AAC1D,eAAO,MAAM,UAAU,uBAAiB,CAAC"}
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;AAmJvD;;;;GAIG;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,CAsCjB;AAqDD;;;;;;;;;;;;;;GAcG;AACH,iBAAe,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CA8ChE;AAOD,eAAO,MAAM,kBAAkB;;;CAG9B,CAAC;AAGF,qDAAqD;AACrD,eAAO,MAAM,qBAAqB,kBAAY,CAAC;AAC/C,0DAA0D;AAC1D,eAAO,MAAM,UAAU,uBAAiB,CAAC"}
@@ -130,12 +130,21 @@ async function withTimeout(promise, ms, label) {
130
130
  clearTimeout(timer);
131
131
  }
132
132
  }
133
- /** One un-retried LLM translate attempt. Lazy-imports the provider factory so
134
- * this module stays light (utils/helpers re-exports it) and to avoid an
135
- * import cycle with the aiGen layer. */
136
- async function callLlmTranslateOnce(text, from, to) {
133
+ /** Lazy-loads the provider factory so this module stays light (utils/helpers
134
+ * re-exports it) and to avoid an import cycle with the aiGen layer.
135
+ *
136
+ * 2026-09-28: the retry loops await this BEFORE starting the per-attempt
137
+ * timer. The import pulls in the whole provider graph, and on a cold or busy
138
+ * api instance (concurrency 80) that alone could burn most of an 8s attempt —
139
+ * prod logged both attempts "timed out after 8000ms" (kk→en) while OpenAI
140
+ * itself answers the same prompt in ~2-4s. */
141
+ async function loadFallbackService() {
137
142
  const { getAiGenProviderService } = await Promise.resolve().then(() => __importStar(require("../aiGen/aiGenFactory.service")));
138
- const service = getAiGenProviderService(FALLBACK_MODEL);
143
+ return getAiGenProviderService(FALLBACK_MODEL);
144
+ }
145
+ /** One un-retried LLM translate attempt. */
146
+ async function callLlmTranslateOnce(text, from, to) {
147
+ const service = await loadFallbackService();
139
148
  const target = languageLabel(to);
140
149
  const system = `You are a professional translation engine. Translate the user's text into ${target}. ` +
141
150
  `Preserve meaning, tone, names, numbers, hashtags, emojis and line breaks. ` +
@@ -158,6 +167,7 @@ async function callLlmTranslateOnce(text, from, to) {
158
167
  /** FALLBACK: translate via a cheap LLM, with a real retry — see the
159
168
  * FALLBACK_ATTEMPT_TIMEOUT_MS comment above for why one shot wasn't enough. */
160
169
  async function callLlmTranslate(text, from, to) {
170
+ await loadFallbackService(); // outside the timer — see loadFallbackService
161
171
  let lastErr;
162
172
  for (let attempt = 1; attempt <= FALLBACK_MAX_ATTEMPTS; attempt++) {
163
173
  try {
@@ -216,8 +226,7 @@ async function translate(text, from, to = types_1.ELANGUAGE_CODE.en, version = "
216
226
  }
217
227
  /** One un-retried LLM detect attempt. */
218
228
  async function callLlmDetectOnce(text) {
219
- const { getAiGenProviderService } = await Promise.resolve().then(() => __importStar(require("../aiGen/aiGenFactory.service")));
220
- const service = getAiGenProviderService(FALLBACK_MODEL);
229
+ const service = await loadFallbackService();
221
230
  const system = "You are a language identification engine. Reply with ONLY the ISO 639-1 " +
222
231
  "code of the language the user's text is written in — two lowercase " +
223
232
  'letters, nothing else (e.g. "es", "ja", "ar"). Use "zh-cn" or "zh-tw" ' +
@@ -248,6 +257,7 @@ async function callLlmDetectOnce(text) {
248
257
  * "default to en" path below — hence the same per-attempt bound as translate.
249
258
  */
250
259
  async function callLlmDetect(text) {
260
+ await loadFallbackService(); // outside the timer — see loadFallbackService
251
261
  let lastErr;
252
262
  for (let attempt = 1; attempt <= FALLBACK_MAX_ATTEMPTS; attempt++) {
253
263
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vidspotai-shared",
3
- "version": "1.0.122-dev.0",
3
+ "version": "1.0.123",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "exports": {