vidspotai-shared 1.0.79 → 1.0.80

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.
@@ -1 +1 @@
1
- {"version":3,"file":"google.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/google/google.service.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AA6IlB,qBAAa,aAAc,SAAQ,wBAAwB;IACzD,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAK;;IAO/C;;;;OAIG;YACW,kBAAkB;IA+B1B,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAqF3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA0F3C,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAsGjC;;;;;;OAMG;IACG,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAqEjC,aAAa,CAAC,EAAE,QAAQ,EAAE,QAAY,EAAE,UAAmB,EAAE,SAAiB,EAAE,SAAa,EAAE,SAAS,EAAE,EAAE,iBAAiB,GAAG,MAAM;CA8BvI"}
1
+ {"version":3,"file":"google.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/google/google.service.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAoJlB,qBAAa,aAAc,SAAQ,wBAAwB;IACzD,OAAO,CAAC,EAAE,CAAc;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAK;;IAO/C;;;;OAIG;YACW,kBAAkB;IA+B1B,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAyG3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IA0F3C,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAsGjC;;;;;;OAMG;IACG,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAqEjC,aAAa,CAAC,EAAE,QAAQ,EAAE,QAAY,EAAE,UAAmB,EAAE,SAAiB,EAAE,SAAa,EAAE,SAAS,EAAE,EAAE,iBAAiB,GAAG,MAAM;CA8BvI"}
@@ -127,13 +127,18 @@ function classifyGoogleApiError(err) {
127
127
  if (httpCode === 14 || /high demand/i.test(msg)) {
128
128
  return new errors_1.UserFacingError(msg, errors_1.USER_FACING_ERROR_CODES.VIDEO_PROVIDER_HIGH_DEMAND);
129
129
  }
130
- // INVALID_ARGUMENT 400 — typically "Your use case is currently not
131
- // supported" when the request mixes features the chosen Veo variant
132
- // doesn't offer (e.g. referenceImages on -fast, lastFrame on -lite,
133
- // video-extension with a non-Veo source URL). Not actionable as a
134
- // platform bug surface as a translatable capability mismatch so the
135
- // user can switch model/feature combo instead of firing Slack.
136
- if (status === "INVALID_ARGUMENT" || httpCode === 400) {
130
+ // INVALID_ARGUMENT 400 — narrow match: only the specific "use case is
131
+ // currently not supported" string, which Veo returns when our request
132
+ // structure doesn't match the chosen model variant's capabilities.
133
+ // The pre-call guards above (duration=8 for lastFrame/refs) should
134
+ // prevent the known cases; if we still hit this it's a NEW combo we
135
+ // haven't profiled surface as CAPABILITY_MISMATCH so the user gets a
136
+ // useful message, AND keep the raw provider text in the error so the
137
+ // next entry in PROD_FIX_LOG can identify which combo broke. Generic
138
+ // 400s (other INVALID_ARGUMENT variants) still surface as `error` so
139
+ // a real platform bug isn't muted.
140
+ if ((status === "INVALID_ARGUMENT" || httpCode === 400) &&
141
+ /use case is currently not supported/i.test(msg)) {
137
142
  return new errors_1.UserFacingError(msg, errors_1.USER_FACING_ERROR_CODES.CAPABILITY_MISMATCH);
138
143
  }
139
144
  }
@@ -192,6 +197,21 @@ class GoogleService extends baseAiGenProvider_service_1.BaseAiGenProviderService
192
197
  const modelConfig = aiModels_1.aiModelConfigs[params.modelKey];
193
198
  const modelId = modelConfig.modelId;
194
199
  const isVeo3_1 = VEO_3_1_MODELS.has(params.modelKey);
200
+ // Gemini Veo cross-constraint: first+last-frame interpolation AND
201
+ // reference images BOTH require durationSeconds=8. Sending any other
202
+ // duration returns INVALID_ARGUMENT 400 "Your use case is currently not
203
+ // supported." with no hint about which param caused it. Surface a
204
+ // typed UserFacingError so the user/frontend can correct the input
205
+ // instead of burning a provider call + opaque rejection.
206
+ const needsDuration8 = !!params.lastFrameImageUrl ||
207
+ (isVeo3_1 && (params.referenceImageUrls?.length ?? 0) > 0);
208
+ if (needsDuration8 && params.duration !== undefined && params.duration !== 8) {
209
+ const constraint = params.lastFrameImageUrl
210
+ ? "first-frame + last-frame interpolation"
211
+ : "reference images";
212
+ throw new errors_1.UserFacingError(`Google Veo requires an 8-second duration when using ${constraint}. ` +
213
+ `Please select 8s or remove the ${params.lastFrameImageUrl ? "last-frame image" : "reference images"}.`, errors_1.USER_FACING_ERROR_CODES.CAPABILITY_MISMATCH);
214
+ }
195
215
  const request = {
196
216
  model: modelId,
197
217
  prompt: params.prompt,
@@ -1 +1 @@
1
- {"version":3,"file":"openai.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/openai/openai.service.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAElB,qBAAa,aAAc,SAAQ,wBAAwB;IACzD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,MAAM,CAAS;;IAQjB,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IAgE3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAsC3C,YAAY,CAChB,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,oBAAoB,CAAC;IA2ChC;;;;OAIG;IACG,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA6HjC,aAAa,CAAC,EACZ,QAAQ,EACR,UAAuB,EACvB,QAAY,EACZ,SAAiB,EACjB,SAAa,EACb,OAAO,GACR,EAAE,iBAAiB,GAAG,MAAM;CAoB9B"}
1
+ {"version":3,"file":"openai.service.d.ts","sourceRoot":"","sources":["../../../../../src/services/aiGen/providers/openai/openai.service.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,wBAAwB,EAAE,MAAM,8BAA8B,CAAC;AACxE,OAAO,EACL,iBAAiB,EACjB,qBAAqB,EACrB,qBAAqB,EACrB,oBAAoB,EACpB,oBAAoB,EACpB,qBAAqB,EACrB,qBAAqB,EACrB,iBAAiB,EACjB,iBAAiB,EAClB,MAAM,UAAU,CAAC;AAElB,qBAAa,aAAc,SAAQ,wBAAwB;IACzD,OAAO,CAAC,QAAQ,CAAC,UAAU,CAAa;IACxC,OAAO,CAAC,MAAM,CAAS;;IAQjB,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA0E3B,gBAAgB,CAAC,EACrB,IAAI,EACJ,cAAc,EACd,cAAyB,GAC1B,EAAE,iBAAiB,GAAG,OAAO,CAAC,iBAAiB,CAAC;IAsC3C,YAAY,CAChB,MAAM,EAAE,oBAAoB,GAC3B,OAAO,CAAC,oBAAoB,CAAC;IA2ChC;;;;OAIG;IACG,aAAa,CACjB,MAAM,EAAE,qBAAqB,GAC5B,OAAO,CAAC,qBAAqB,CAAC;IA6HjC,aAAa,CAAC,EACZ,QAAQ,EACR,UAAuB,EACvB,QAAY,EACZ,SAAiB,EACjB,SAAa,EACb,OAAO,GACR,EAAE,iBAAiB,GAAG,MAAM;CAoB9B"}
@@ -61,17 +61,29 @@ class OpenaiService extends baseAiGenProvider_service_1.BaseAiGenProviderService
61
61
  };
62
62
  // First-frame image-to-video. The Sora API requires the reference image
63
63
  // dimensions to match `size`; the caller is responsible for that.
64
- // Note: openai SDK v6.3.0 does NOT yet expose extensions / characters /
65
- // edits endpoints — those exist in the REST API but are not surfaced here.
64
+ //
65
+ // We use the JSON variant `input_reference: { image_url }` (OpenAI
66
+ // fetches the image themselves) rather than the multipart `Uploadable`
67
+ // shape. Reason: as of late 2026 sora-2-pro started returning
68
+ // 400 Invalid type for 'input_reference': expected an object, but
69
+ // got a file instead.
70
+ // for multipart uploads that worked on sora-2. The JSON form is
71
+ // documented for both models and avoids the size mismatch entirely.
72
+ //
73
+ // openai SDK 6.3.0's typed shape for input_reference is `Uploadable`
74
+ // (no JSON-object overload yet), so we bypass the type with a cast.
75
+ // The HTTP layer serializes plain objects as JSON automatically when
76
+ // no Uploadable is present in the body, which is exactly what we want.
77
+ //
78
+ // Note: openai SDK v6.3.0 does NOT yet expose extensions / characters
79
+ // / edits endpoints — those exist in the REST API but are not surfaced.
66
80
  if (params.inputImageUrl) {
67
- const resp = await fetch(params.inputImageUrl);
68
- // fetch() does not throw on 4xx/5xx surface the HTTP error so we
69
- // don't ship an HTML error page to Sora as if it were image bytes.
70
- if (!resp.ok) {
71
- throw new errors_1.UserFacingError(`Input image could not be downloaded (HTTP ${resp.status}). The image URL may have expired or been deleted.`);
72
- }
73
- const filename = (params.inputImageUrl.split("?")[0] ?? "reference").split("/").pop() || "reference.png";
74
- request.input_reference = await (0, openai_1.toFile)(resp, filename);
81
+ // SDK 6.3.0 types input_reference as Uploadable only; the JSON
82
+ // object form is a runtime-supported overload that the types
83
+ // haven't caught up to yet. Bypass via unknown cast.
84
+ request.input_reference = {
85
+ image_url: params.inputImageUrl,
86
+ };
75
87
  }
76
88
  let job;
77
89
  try {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vidspotai-shared",
3
- "version": "1.0.79",
3
+ "version": "1.0.80",
4
4
  "main": "lib/index.js",
5
5
  "types": "lib/index.d.ts",
6
6
  "exports": {