@braze/sanity-plugin-ai-translation 0.2.55 → 0.2.57

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1527,8 +1527,35 @@ const globalTransformRegistry = new TransformRegistry(), callGPT5 = async (apiKe
1527
1527
  }, modelPricing = pricing[model] || pricing["gpt-5"], cachedInputRate = model === "gpt-5.1" ? 0.125 / 1e6 : modelPricing.input;
1528
1528
  return Math.max(0, tokens.prompt - tokens.cached) * modelPricing.input + tokens.cached * cachedInputRate + tokens.completion * modelPricing.output + tokens.reasoning * modelPricing.reasoning;
1529
1529
  }, deserializeDocument = (originalDoc, reviewedText) => {
1530
- const parsed = parseReviewFormat(reviewedText, originalDoc), result = cloneDeep(originalDoc);
1530
+ devLog.debug("Raw GPT-5 response received", {
1531
+ length: reviewedText.length,
1532
+ preview: reviewedText.substring(0, 1e3),
1533
+ hasReasoning: reviewedText.includes("<reasoning>"),
1534
+ hasCodeBlocks: reviewedText.includes("```")
1535
+ });
1536
+ const cleanedText = preprocessResponse(reviewedText);
1537
+ cleanedText.length !== reviewedText.length && devLog.debug("Response after preprocessing", {
1538
+ originalLength: reviewedText.length,
1539
+ cleanedLength: cleanedText.length,
1540
+ preview: cleanedText.substring(0, 500)
1541
+ });
1542
+ const parsed = parseReviewFormat(cleanedText, originalDoc), result = cloneDeep(originalDoc);
1531
1543
  return applyTextChanges(result, parsed), result;
1544
+ }, preprocessResponse = (text) => {
1545
+ const originalLength = text.length;
1546
+ let cleaned = text;
1547
+ const beforeReasoning = cleaned.length;
1548
+ cleaned = cleaned.replace(/<reasoning>[\s\S]*?<\/reasoning>/gi, "");
1549
+ const reasoningRemoved = beforeReasoning !== cleaned.length, beforeCodeBlocks = cleaned.length;
1550
+ cleaned = cleaned.replace(/^```[a-z]*\s*$/gim, ""), cleaned = cleaned.replace(/^```\s*$/gim, "");
1551
+ const codeBlocksRemoved = beforeCodeBlocks !== cleaned.length, finalLength = cleaned.trim().length;
1552
+ return (reasoningRemoved || codeBlocksRemoved) && devLog.debug("Preprocessed GPT-5 response", {
1553
+ originalLength,
1554
+ finalLength,
1555
+ reasoningRemoved,
1556
+ codeBlocksRemoved,
1557
+ preview: cleaned.trim().substring(0, 200)
1558
+ }), cleaned.trim();
1532
1559
  }, parseReviewFormat = (text, originalDoc) => {
1533
1560
  const root = [], stack = [], lines = text.split(`
1534
1561
  `);
@@ -3902,10 +3929,14 @@ function serializeVTTCaptionText(captions) {
3902
3929
  firstCaption: captions.length > 0 ? captions[0] : null
3903
3930
  }), !Array.isArray(captions) || captions.length === 0)
3904
3931
  return "";
3905
- const result = captions.map((caption, index) => (devLog.debug(`Processing caption ${index}:`, {
3906
- text: caption.text,
3907
- hasText: typeof caption.text == "string"
3908
- }), `[${index}] ${caption.text || ""}`)).join(`
3932
+ const result = captions.map((caption, index) => {
3933
+ devLog.debug(`Processing caption ${index}:`, {
3934
+ text: caption.text,
3935
+ hasText: typeof caption.text == "string"
3936
+ });
3937
+ const escapedText = (caption.text || "").replace(/\n/g, "\\n");
3938
+ return `[${index}] ${escapedText}`;
3939
+ }).join(`
3909
3940
  `);
3910
3941
  return devLog.debug("serializeVTTCaptionText - output:", {
3911
3942
  resultLength: result.length,
@@ -3922,29 +3953,46 @@ function deserializeVTTCaptionText(translationText, originalMetadata) {
3922
3953
  return [];
3923
3954
  const result = [], lines = translationText.split(`
3924
3955
  `), lineRegex = /^\[(\d+)\]\s*(.*)$/;
3956
+ let currentIndex = null, currentTextParts = [];
3925
3957
  for (const line of lines) {
3926
3958
  const match = line.match(lineRegex);
3927
- if (!match) {
3928
- devLog.warn("Failed to parse caption line", { line });
3929
- continue;
3930
- }
3931
- const index = Number.parseInt(match[1], 10), text = match[2];
3932
- devLog.debug("Found caption:", {
3933
- index,
3934
- text
3935
- });
3936
- const metadata = originalMetadata.find((m) => m._originalIndex === index);
3959
+ if (match) {
3960
+ if (currentIndex !== null) {
3961
+ const text = currentTextParts.join(`
3962
+ `).replace(/\\n/g, `
3963
+ `), metadata = originalMetadata.find((m) => m._originalIndex === currentIndex);
3964
+ if (metadata) {
3965
+ const { _originalIndex, ...metadataWithoutIndex } = metadata;
3966
+ result.push({
3967
+ ...metadataWithoutIndex,
3968
+ text
3969
+ });
3970
+ } else
3971
+ devLog.warn("Missing metadata for caption", { index: currentIndex }), result.push({
3972
+ _type: "vtt.cue",
3973
+ _key: `caption-${currentIndex}`,
3974
+ text,
3975
+ startTime: 0,
3976
+ endTime: 0
3977
+ });
3978
+ }
3979
+ currentIndex = Number.parseInt(match[1], 10), currentTextParts = [match[2]];
3980
+ } else currentIndex !== null ? currentTextParts.push(line) : devLog.warn("Failed to parse caption line", { line });
3981
+ }
3982
+ if (currentIndex !== null) {
3983
+ const text = currentTextParts.join(`
3984
+ `).replace(/\\n/g, `
3985
+ `), metadata = originalMetadata.find((m) => m._originalIndex === currentIndex);
3937
3986
  if (metadata) {
3938
- devLog.debug(`Found matching metadata for index ${index}`);
3939
3987
  const { _originalIndex, ...metadataWithoutIndex } = metadata;
3940
3988
  result.push({
3941
3989
  ...metadataWithoutIndex,
3942
3990
  text
3943
3991
  });
3944
3992
  } else
3945
- devLog.warn("Missing metadata for caption", { index }), result.push({
3993
+ devLog.warn("Missing metadata for caption", { index: currentIndex }), result.push({
3946
3994
  _type: "vtt.cue",
3947
- _key: `caption-${index}`,
3995
+ _key: `caption-${currentIndex}`,
3948
3996
  text,
3949
3997
  startTime: 0,
3950
3998
  endTime: 0
@@ -4181,10 +4229,14 @@ function serializeWistiaCaptionText(cues) {
4181
4229
  firstCue: cues.length > 0 ? cues[0] : null
4182
4230
  }), !Array.isArray(cues) || cues.length === 0)
4183
4231
  return "";
4184
- const result = cues.map((cue) => (devLog.debug(`Processing cue ${cue.index}:`, {
4185
- text: cue.text,
4186
- hasText: typeof cue.text == "string"
4187
- }), `[${cue.index}] ${cue.text}`)).join(`
4232
+ const result = cues.map((cue) => {
4233
+ devLog.debug(`Processing cue ${cue.index}:`, {
4234
+ text: cue.text,
4235
+ hasText: typeof cue.text == "string"
4236
+ });
4237
+ const escapedText = cue.text.replace(/\n/g, "\\n");
4238
+ return `[${cue.index}] ${escapedText}`;
4239
+ }).join(`
4188
4240
  `);
4189
4241
  return devLog.debug("serializeWistiaCaptionText - output:", {
4190
4242
  resultLength: result.length,
@@ -4203,19 +4255,24 @@ function deserializeWistiaCaptionText(translationText, srtCuesMetadata) {
4203
4255
  `), lineRegex = /^\[(\d+)\]\s*(.*)$/, metadataByIndex = /* @__PURE__ */ new Map();
4204
4256
  for (const metadata of srtCuesMetadata)
4205
4257
  metadataByIndex.set(metadata.index, { startTime: metadata.startTime, endTime: metadata.endTime });
4258
+ let currentIndex = null, currentTextParts = [];
4206
4259
  for (const line of lines) {
4207
4260
  const match = line.match(lineRegex);
4208
- if (!match) {
4209
- devLog.warn("Failed to parse caption line", { line });
4210
- continue;
4211
- }
4212
- const index = Number.parseInt(match[1], 10), text = match[2];
4213
- devLog.debug("Found caption:", {
4214
- index,
4215
- text
4216
- });
4217
- const metadata = metadataByIndex.get(index);
4218
- metadata ? (devLog.debug(`Found matching metadata for index ${index}`), result.push(`${index}`), result.push(`${metadata.startTime} --> ${metadata.endTime}`), result.push(text), result.push("")) : devLog.warn("Missing metadata for caption", { index });
4261
+ if (match) {
4262
+ if (currentIndex !== null) {
4263
+ const text = currentTextParts.join(`
4264
+ `).replace(/\\n/g, `
4265
+ `), metadata = metadataByIndex.get(currentIndex);
4266
+ metadata ? (result.push(`${currentIndex}`), result.push(`${metadata.startTime} --> ${metadata.endTime}`), result.push(text), result.push("")) : devLog.warn("Missing metadata for caption", { index: currentIndex });
4267
+ }
4268
+ currentIndex = Number.parseInt(match[1], 10), currentTextParts = [match[2]];
4269
+ } else currentIndex !== null ? currentTextParts.push(line) : devLog.warn("Failed to parse caption line", { line });
4270
+ }
4271
+ if (currentIndex !== null) {
4272
+ const text = currentTextParts.join(`
4273
+ `).replace(/\\n/g, `
4274
+ `), metadata = metadataByIndex.get(currentIndex);
4275
+ metadata ? (result.push(`${currentIndex}`), result.push(`${metadata.startTime} --> ${metadata.endTime}`), result.push(text), result.push("")) : devLog.warn("Missing metadata for caption", { index: currentIndex });
4219
4276
  }
4220
4277
  result.length > 0 && result[result.length - 1] === "" && result.pop();
4221
4278
  const reconstructed = result.join(`