@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/README.md +394 -191
- package/dist/index.js +90 -33
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
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
|
-
|
|
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) =>
|
|
3906
|
-
|
|
3907
|
-
|
|
3908
|
-
|
|
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 (
|
|
3928
|
-
|
|
3929
|
-
|
|
3930
|
-
|
|
3931
|
-
|
|
3932
|
-
|
|
3933
|
-
|
|
3934
|
-
|
|
3935
|
-
|
|
3936
|
-
|
|
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-${
|
|
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) =>
|
|
4185
|
-
|
|
4186
|
-
|
|
4187
|
-
|
|
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 (
|
|
4209
|
-
|
|
4210
|
-
|
|
4211
|
-
|
|
4212
|
-
|
|
4213
|
-
|
|
4214
|
-
|
|
4215
|
-
|
|
4216
|
-
});
|
|
4217
|
-
|
|
4218
|
-
|
|
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(`
|