@braze/sanity-plugin-ai-translation 0.1.5 → 0.1.7

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.d.ts CHANGED
@@ -27,6 +27,7 @@ declare interface PluginConfig {
27
27
  languageFieldName: string;
28
28
  schemaId: string;
29
29
  maxConcurrentTranslationJobs?: number;
30
+ maxReferenceDepth?: number;
30
31
  }
31
32
 
32
33
  /**
package/dist/index.js CHANGED
@@ -118,17 +118,24 @@ async function applySuggestions({
118
118
  suggestions,
119
119
  onProgress
120
120
  }) {
121
- devLog.info("Applying suggestions", {
121
+ if (devLog.info("Applying suggestions", {
122
122
  sourceLanguage,
123
123
  targetLanguage,
124
+ targetLanguageType: typeof targetLanguage,
125
+ targetLanguageValue: targetLanguage,
124
126
  count: suggestions.filter((s) => s.approved).length
125
- });
127
+ }), !targetLanguage)
128
+ throw devLog.error("targetLanguage is undefined in applySuggestions!", {
129
+ sourceLanguage,
130
+ targetLanguage,
131
+ suggestionsCount: suggestions.length
132
+ }), new Error("targetLanguage is required but was undefined");
126
133
  const approvedSuggestions = suggestions.filter((s) => s.approved);
127
134
  if (approvedSuggestions.length === 0) {
128
135
  devLog.info("No approved suggestions to apply");
129
136
  return;
130
137
  }
131
- onProgress?.({ stage: "applying", message: "Applying updates to translation settings..." }), await applyImprovementsFromSuggestions(client, schemaId, sourceLanguage, approvedSuggestions, onProgress), devLog.info("Suggestions applied successfully");
138
+ onProgress?.({ stage: "applying", message: "Applying updates to translation settings..." }), await applyImprovementsFromSuggestions(client, schemaId, targetLanguage, approvedSuggestions, onProgress), devLog.info("Suggestions applied successfully");
132
139
  }
133
140
  function buildAnalysisPrompt({
134
141
  sourceLanguage,
@@ -203,7 +210,7 @@ function buildAnalysisPrompt({
203
210
  ' "globalPromptUpdates": "string | null - ONLY if this applies to ALL language pairs",',
204
211
  ` "localePromptUpdates": "string | null - ONLY if this is specific to ${sourceLanguage}\u2192${targetLanguage}",`,
205
212
  ' "protectedPhrasesToAdd": ["ONLY brand names, products, proper nouns that should NEVER translate"],',
206
- ' "glossaryTermsToAdd": [{"sourceValue": "term", "targetValue": "translation"} - ONLY specific term mappings],',
213
+ ' "glossaryTermsToAdd": [{"sourceLocale": "sourceLocale","sourceValue": "term", "targetLocale": "targetLocale", "targetValue": "translation"} - ONLY specific term mappings],',
207
214
  ' "reasoning": "string - Explain your analysis and which mechanism you chose for each issue"',
208
215
  "}",
209
216
  "",
@@ -240,7 +247,9 @@ function convertAnalysisToSuggestions(analysis) {
240
247
  type: "glossaryTerm",
241
248
  description: `${term.sourceValue} \u2192 ${term.targetValue}`,
242
249
  approved: !0,
250
+ sourceLocale: term.sourceLocale,
243
251
  sourceValue: term.sourceValue,
252
+ targetLocale: term.targetLocale,
244
253
  targetValue: term.targetValue
245
254
  });
246
255
  return suggestions;
@@ -286,7 +295,7 @@ function parseAIResponse(responseText) {
286
295
  throw devLog.error("Error parsing AI response", { error, responseText }), new Error("Failed to parse AI response as JSON");
287
296
  }
288
297
  }
289
- async function applyImprovementsFromSuggestions(client, sourceLanguage, targetLanguage, suggestions, onProgress) {
298
+ async function applyImprovementsFromSuggestions(client, schemaId, targetLanguage, suggestions, onProgress) {
290
299
  devLog.info("Applying improvements from suggestions", { count: suggestions.length });
291
300
  const settingsId = "translation-settings";
292
301
  await client.fetch("*[_id == $id][0]", { id: settingsId }) || await client.createIfNotExists({
@@ -294,28 +303,17 @@ async function applyImprovementsFromSuggestions(client, sourceLanguage, targetLa
294
303
  _type: "translationSettings"
295
304
  });
296
305
  const updates = [], globalPrompts = suggestions.filter((s) => s.type === "globalPrompt" && s.description.trim()), localePrompts = suggestions.filter((s) => s.type === "localePrompt" && s.description.trim()), protectedPhrases = suggestions.filter((s) => s.type === "protectedPhrase" && s.description.trim()), glossaryTerms = suggestions.filter(
297
- (s) => s.type === "glossaryTerm" && s.sourceValue?.trim() && s.targetValue?.trim()
306
+ (s) => s.type === "glossaryTerm" && s.sourceLocale?.trim() && s.sourceValue?.trim() && s.targetLocale?.trim() && s.targetValue?.trim()
298
307
  );
299
308
  if (devLog.info("Filtered suggestions by type", {
300
309
  globalPrompts: globalPrompts.length,
301
310
  localePrompts: localePrompts.length,
302
311
  protectedPhrases: protectedPhrases.length,
303
312
  glossaryTerms: glossaryTerms.length
304
- }), globalPrompts.length > 0) {
305
- onProgress?.({ stage: "applying", message: "Updating global translation prompt..." });
306
- const combinedUpdate = globalPrompts.map((s) => s.description).join(`
307
-
308
- `);
309
- devLog.debug("Applying global prompt update", { combinedUpdate }), updates.push(updateGlobalPrompt(client, settingsId, combinedUpdate));
310
- }
311
- if (localePrompts.length > 0) {
312
- onProgress?.({ stage: "applying", message: `Updating ${targetLanguage} translation prompt...` });
313
- const combinedUpdate = localePrompts.map((s) => s.description).join(`
314
-
315
- `);
316
- devLog.debug("Applying locale prompt update", { targetLanguage, combinedUpdate }), updates.push(updateLocalePrompt(client, settingsId, targetLanguage, combinedUpdate));
317
- }
318
- if (protectedPhrases.length > 0) {
313
+ }), (globalPrompts.length > 0 || localePrompts.length > 0) && (onProgress?.({
314
+ stage: "applying",
315
+ message: globalPrompts.length > 0 && localePrompts.length > 0 ? "Updating global and locale translation prompts..." : globalPrompts.length > 0 ? "Updating global translation prompt..." : `Updating ${targetLanguage} translation prompt...`
316
+ }), updates.push(updatePromptsWithTransform(client, schemaId, settingsId, targetLanguage, globalPrompts, localePrompts))), protectedPhrases.length > 0) {
319
317
  onProgress?.({ stage: "applying", message: "Adding protected phrases..." });
320
318
  const phrases = protectedPhrases.map((s) => s.description);
321
319
  devLog.debug("Applying protected phrases", { phrases }), updates.push(addProtectedPhrases(client, settingsId, phrases));
@@ -324,77 +322,118 @@ async function applyImprovementsFromSuggestions(client, sourceLanguage, targetLa
324
322
  onProgress?.({ stage: "applying", message: "Adding glossary terms..." });
325
323
  const terms = glossaryTerms.map((s) => ({
326
324
  // biome-ignore-start lint/style/noNonNullAssertion: safely handled
325
+ sourceLocale: s.sourceLocale,
327
326
  sourceValue: s.sourceValue,
327
+ targetLocale: s.targetLocale,
328
328
  targetValue: s.targetValue
329
329
  // biome-ignore-end lint/style/noNonNullAssertion: safely handled
330
330
  }));
331
- devLog.debug("Applying glossary terms", { terms }), updates.push(addGlossaryTerms(client, terms, sourceLanguage, targetLanguage));
331
+ devLog.debug("Applying glossary terms", { terms }), updates.push(addGlossaryTerms(client, terms));
332
332
  }
333
333
  updates.length === 0 && devLog.warn("No valid updates to apply - all suggestions may have been empty"), await Promise.all(updates), devLog.info("All improvements applied successfully");
334
334
  }
335
- async function mergePromptWithAI(client, currentPrompt, newGuidance, context) {
336
- const instruction = `
337
- You are updating a ${context === "global" ? "translation" : `locale-specific translation for ${context}`} prompt.
338
- Your task is to merge new guidance into an existing prompt.
335
+ async function updatePromptsWithTransform(client, schemaId, settingsId, targetLanguage, globalPrompts, localePrompts) {
336
+ if (devLog.info("Updating prompts with transform action", {
337
+ settingsId,
338
+ targetLanguage,
339
+ targetLanguageType: typeof targetLanguage,
340
+ targetLanguageValue: targetLanguage,
341
+ hasGlobalUpdates: globalPrompts.length > 0,
342
+ hasLocaleUpdates: localePrompts.length > 0
343
+ }), !targetLanguage)
344
+ throw devLog.error("targetLanguage is undefined or empty!", {
345
+ targetLanguage,
346
+ globalPrompts: globalPrompts.length,
347
+ localePrompts: localePrompts.length
348
+ }), new Error("targetLanguage is required but was undefined");
349
+ const targets = [];
350
+ if (globalPrompts.length > 0) {
351
+ const combinedGlobalUpdate = globalPrompts.map((s) => s.description).join(`
339
352
 
340
- CURRENT PROMPT:
341
- ${currentPrompt}
353
+ `);
354
+ targets.push({
355
+ path: "globalPrompt",
356
+ instruction: `You are updating a translation prompt document that contains rules and guidance for future AI translations.
342
357
 
343
- NEW GUIDANCE TO ADD:
344
- ${newGuidance}
358
+ IMPORTANT: The text below is NEW GUIDANCE that should be INCORPORATED INTO the existing prompt as additional rules/instructions for future translations. DO NOT apply or execute these rules on the prompt text itself.
345
359
 
346
- INSTRUCTIONS:
347
- - Read the current prompt carefully
348
- - Integrate the new guidance into the prompt in a natural, coherent way
349
- - If the new guidance conflicts with existing content, update or replace the conflicting parts
350
- - If the new guidance is already covered, do not add redundant text
351
- - Maintain the structure and tone of the prompt
352
- - Output ONLY the updated prompt text, with no preamble or explanation
360
+ Your task: Merge the new guidance below into the existing prompt text. Treat the new guidance as rules that will guide future translations, not as transformations to apply to the current text.
353
361
 
354
- OUTPUT THE UPDATED PROMPT:`.trim(), mergedPrompt = await client.agent.action.prompt({
355
- instruction,
356
- format: "string"
357
- });
358
- return devLog.debug("AI merged prompt", {
359
- context,
360
- originalLength: currentPrompt.length,
361
- newLength: mergedPrompt.length
362
- }), mergedPrompt;
363
- }
364
- async function updateGlobalPrompt(client, settingsId, updates) {
365
- devLog.info("Updating global prompt", { settingsId, updatesLength: updates.length });
366
- const currentPrompt = await client.fetch("*[_id == $settingsId][0].globalPrompt", { settingsId });
367
- devLog.debug("Fetched current global prompt", {
368
- hasCurrentPrompt: !!currentPrompt,
369
- currentLength: currentPrompt?.length
370
- });
371
- const newPrompt = currentPrompt ? await mergePromptWithAI(client, currentPrompt, updates, "global") : updates, result = await client.patch(settingsId).set({ globalPrompt: newPrompt.trim() }).commit();
372
- devLog.info("Global prompt updated", { resultId: result._id, newPromptLength: newPrompt.length });
373
- }
374
- async function updateLocalePrompt(client, settingsId, locale, updates) {
375
- devLog.info("Updating locale prompt", { settingsId, locale, updatesLength: updates.length });
376
- const currentLocalePrompts = await client.fetch(
377
- "*[_id == $settingsId][0].localePrompts",
378
- { settingsId }
379
- );
380
- devLog.debug("Fetched current locale prompts", { count: currentLocalePrompts?.length });
381
- const existingPrompt = currentLocalePrompts?.find((lp) => lp.locale === locale);
382
- if (devLog.debug("Found existing prompt for locale", { locale, hasExisting: !!existingPrompt }), existingPrompt?.prompt) {
383
- const newPrompt = await mergePromptWithAI(client, existingPrompt.prompt, updates, locale), updatedPrompts = currentLocalePrompts.map(
384
- (lp) => lp.locale === locale ? { ...lp, prompt: newPrompt.trim() } : lp
385
- ), result = await client.patch(settingsId).set({ localePrompts: updatedPrompts }).commit();
386
- devLog.info("Locale prompt updated (merged)", { locale, resultId: result._id });
387
- } else {
388
- const result = await client.patch(settingsId).setIfMissing({ localePrompts: [] }).append("localePrompts", [
362
+ Integration guidelines:
363
+ - Add the new guidance as additional instructions/rules in the prompt
364
+ - If it conflicts with existing guidance, update or replace the conflicting parts
365
+ - If it's already covered, don't add redundant text
366
+ - Maintain clear structure and consistent tone
367
+ - Preserve all existing guidance that is still relevant
368
+ - Keep the prompt written as instructions for a translator (e.g., "When translating, you should..." not "The translation has been...")
369
+
370
+ New guidance to incorporate:
371
+
372
+ \`\`\`
373
+ ${combinedGlobalUpdate}
374
+ \`\`\``
375
+ }), devLog.debug("Added global prompt target", { combinedUpdate: combinedGlobalUpdate });
376
+ }
377
+ if (localePrompts.length > 0) {
378
+ const combinedLocaleUpdate = localePrompts.map((s) => s.description).join(`
379
+
380
+ `), existingLocalePrompts = await client.fetch(
381
+ "*[_id == $settingsId][0].localePrompts",
382
+ { settingsId }
383
+ ), hasExistingLocalePrompt = existingLocalePrompts?.some((lp) => lp._key === targetLanguage);
384
+ devLog.debug("Checking existing locale prompt", {
385
+ targetLanguage,
386
+ hasExistingLocalePrompt,
387
+ existingCount: existingLocalePrompts?.length || 0
388
+ }), hasExistingLocalePrompt || (devLog.info("Creating new locale prompt entry", { targetLanguage }), await client.patch(settingsId).setIfMissing({ localePrompts: [] }).append("localePrompts", [
389
389
  {
390
- _type: "localePrompt",
391
- _key: locale,
392
- locale,
393
- prompt: updates.trim()
390
+ _type: "internationalizedArrayTextValue",
391
+ _key: targetLanguage,
392
+ value: ""
393
+ // Start with empty value, transform will fill it
394
394
  }
395
- ]).commit();
396
- devLog.info("Locale prompt created", { locale, resultId: result._id });
395
+ ]).commit());
396
+ const localePromptPath = ["localePrompts", { _key: targetLanguage }, "value"];
397
+ targets.push({
398
+ // @ts-expect-error
399
+ path: localePromptPath,
400
+ instruction: `You are updating a translation prompt document that contains rules and guidance for future AI translations.
401
+
402
+ IMPORTANT: The text below is NEW GUIDANCE that should be INCORPORATED INTO the existing prompt as additional rules/instructions for future translations. DO NOT apply or execute these rules on the prompt text itself.
403
+
404
+ Your task: Merge the new guidance below into the existing prompt text. Treat the new guidance as rules that will guide future translations, not as transformations to apply to the current text.
405
+
406
+ Integration guidelines:
407
+ - Add the new guidance as additional instructions/rules in the prompt
408
+ - If it conflicts with existing guidance, update or replace the conflicting parts
409
+ - If it's already covered, don't add redundant text
410
+ - Maintain clear structure and consistent tone
411
+ - Preserve all existing guidance that is still relevant
412
+ - Keep the prompt written as instructions for a translator (e.g., "When translating, you should..." not "The translation has been...")
413
+
414
+ New guidance to incorporate:
415
+
416
+ \`\`\`
417
+ ${combinedLocaleUpdate}
418
+ \`\`\``
419
+ }), devLog.debug("Added locale prompt target", {
420
+ targetLanguage,
421
+ localePromptPath,
422
+ combinedUpdate: combinedLocaleUpdate
423
+ });
397
424
  }
425
+ const result = await client.agent.action.transform({
426
+ schemaId,
427
+ documentId: settingsId,
428
+ instruction: "Update translation prompts based on user feedback to improve future translations.",
429
+ target: targets,
430
+ forcePublishedWrite: !0
431
+ });
432
+ devLog.info("Prompts updated via transform action", {
433
+ resultId: result._id,
434
+ globalUpdated: globalPrompts.length > 0,
435
+ localeUpdated: localePrompts.length > 0
436
+ });
398
437
  }
399
438
  async function addProtectedPhrases(client, settingsId, phrases) {
400
439
  devLog.info("Adding protected phrases", { settingsId, phrasesCount: phrases.length, phrases });
@@ -408,7 +447,7 @@ async function addProtectedPhrases(client, settingsId, phrases) {
408
447
  const result = await client.patch(settingsId).setIfMissing({ protectedPhrases: [] }).append("protectedPhrases", newPhrases).commit();
409
448
  devLog.info("Protected phrases added", { count: newPhrases.length, phrases: newPhrases, resultId: result._id });
410
449
  }
411
- async function addGlossaryTerms(client, terms, sourceLocale, targetLocale) {
450
+ async function addGlossaryTerms(client, terms) {
412
451
  const validTerms = terms.filter(({ sourceValue, targetValue }) => sourceValue === targetValue ? (devLog.warn("Skipping glossary term where source === target (should be a protected phrase)", {
413
452
  sourceValue,
414
453
  targetValue
@@ -417,38 +456,37 @@ async function addGlossaryTerms(client, terms, sourceLocale, targetLocale) {
417
456
  devLog.info("No valid glossary terms to add");
418
457
  return;
419
458
  }
420
- for (const { sourceValue, targetValue } of validTerms) {
459
+ for (const { sourceLocale, sourceValue, targetLocale, targetValue } of validTerms) {
421
460
  const existingTerm = await client.fetch(
422
- `*[_type == "translationGlossaryTerm"
423
- && count(translations[locale == $sourceLocale && value == $sourceValue]) > 0
461
+ `*[_type == "translationGlossaryTerm" && count(translations[_key == $sourceLocale && value == $sourceValue]) > 0
424
462
  ][0] {
425
463
  _id,
426
464
  translations
427
465
  }`,
428
466
  { sourceLocale, sourceValue }
429
467
  );
430
- existingTerm ? existingTerm.translations.some(
431
- (t) => t.locale === targetLocale && t.value === targetValue
432
- ) ? devLog.info("Glossary term already has this translation", { sourceValue, targetValue, targetLocale }) : (await client.patch(existingTerm._id).append("translations", [
468
+ existingTerm ? existingTerm.translations.some((t) => t._key === targetLocale) ? devLog.info("Glossary term already has this translation", {
469
+ sourceLocale,
470
+ sourceValue,
471
+ targetLocale,
472
+ targetValue
473
+ }) : (await client.patch(existingTerm._id).append("translations", [
433
474
  {
434
- _type: "translation",
475
+ _type: "internationalizedArrayStringValue",
435
476
  _key: targetLocale,
436
- locale: targetLocale,
437
477
  value: targetValue
438
478
  }
439
- ]).commit(), devLog.info("Updated existing glossary term", { sourceValue, targetValue, targetLocale })) : (await client.create({
479
+ ]).commit(), devLog.info("Updated existing glossary term", { sourceLocale, sourceValue, targetLocale, targetValue })) : (await client.create({
440
480
  _type: "translationGlossaryTerm",
441
481
  translations: [
442
482
  {
443
- _type: "translation",
483
+ _type: "internationalizedArrayStringValue",
444
484
  _key: sourceLocale,
445
- locale: sourceLocale,
446
485
  value: sourceValue
447
486
  },
448
487
  {
449
- _type: "translation",
488
+ _type: "internationalizedArrayStringValue",
450
489
  _key: targetLocale,
451
- locale: targetLocale,
452
490
  value: targetValue
453
491
  }
454
492
  ]
@@ -729,7 +767,7 @@ const ICON_SIZE = 64, progressIconMap = {
729
767
  client,
730
768
  schemaId: config.schemaId,
731
769
  sourceLanguage: translationHistory2.sourceLanguage || "en-us",
732
- targetLanguage: document[config.languageFieldName],
770
+ targetLanguage: translationHistory2.language,
733
771
  suggestions,
734
772
  onProgress: ({ stage, message }) => {
735
773
  setProcessingState(stage), setChangeSummary(message);
@@ -972,24 +1010,7 @@ const ICON_SIZE = 64, progressIconMap = {
972
1010
  defineField({
973
1011
  name: "translations",
974
1012
  title: "Translations",
975
- type: "array",
976
- of: [
977
- {
978
- name: "translation",
979
- title: "Translation",
980
- type: "object",
981
- fields: [
982
- defineField({
983
- name: "locale",
984
- type: "string"
985
- }),
986
- defineField({
987
- name: "value",
988
- type: "string"
989
- })
990
- ]
991
- }
992
- ]
1013
+ type: "internationalizedArrayString"
993
1014
  })
994
1015
  ],
995
1016
  preview: {
@@ -1050,21 +1071,6 @@ const ICON_SIZE = 64, progressIconMap = {
1050
1071
  ]
1051
1072
  }
1052
1073
  ]
1053
- }), localePrompt = defineField({
1054
- name: "localePrompt",
1055
- title: "Locale Prompt",
1056
- type: "object",
1057
- fields: [
1058
- defineField({
1059
- name: "locale",
1060
- type: "string"
1061
- }),
1062
- defineField({
1063
- name: "prompt",
1064
- type: "text",
1065
- rows: 5
1066
- })
1067
- ]
1068
1074
  }), translationSettings = defineType({
1069
1075
  name: "translationSettings",
1070
1076
  title: "Translation Settings",
@@ -1082,8 +1088,7 @@ const ICON_SIZE = 64, progressIconMap = {
1082
1088
  name: "localePrompts",
1083
1089
  title: "Locale Prompts",
1084
1090
  description: "Prompts that will be given to the Sanity AI Agent for each locale.",
1085
- type: "array",
1086
- of: [localePrompt]
1091
+ type: "internationalizedArrayText"
1087
1092
  }),
1088
1093
  defineField({
1089
1094
  name: "protectedPhrases",
@@ -1120,9 +1125,9 @@ const ICON_SIZE = 64, progressIconMap = {
1120
1125
  ) || [], glossaryTermsByLocale = {};
1121
1126
  for (const targetLanguage of targetLanguages) {
1122
1127
  const relevantTranslations = translationGlossaryTerms.filter(
1123
- (termTranslations) => termTranslations.some((translation) => translation.locale === targetLanguage)
1128
+ (termTranslations) => termTranslations.some((translation) => translation._key === targetLanguage)
1124
1129
  ).map((termTranslations) => {
1125
- const from = termTranslations.find((translation) => translation.locale === sourceLanguage)?.value, to = termTranslations.find((translation) => translation.locale === targetLanguage)?.value;
1130
+ const from = termTranslations.find((translation) => translation._key === sourceLanguage)?.value, to = termTranslations.find((translation) => translation._key === targetLanguage)?.value;
1126
1131
  return !from || !to ? null : { from, to };
1127
1132
  }).filter((item) => item !== null);
1128
1133
  glossaryTermsByLocale[targetLanguage] = relevantTranslations;
@@ -1134,14 +1139,16 @@ const ICON_SIZE = 64, progressIconMap = {
1134
1139
  targetLanguages.map((locale) => [
1135
1140
  locale,
1136
1141
  {
1137
- prompt: translationSettings2?.localePrompts?.find((lp) => lp.locale === locale)?.prompt,
1142
+ prompt: translationSettings2?.localePrompts?.find((lp) => lp._key === locale)?.value,
1138
1143
  glossaryTerms: formatGlossaryTermInstruction(glossaryTermsByLocale[locale])
1139
1144
  }
1140
1145
  ])
1141
1146
  )
1142
1147
  };
1143
1148
  }, formatGlossaryTermInstruction = (terms) => {
1144
- const instructions = ["Translate the following terms exactly as described below:"];
1149
+ const instructions = [
1150
+ "Translate the following terms exactly as described below. When a term includes a colon, the suffix following the colon describes how the term should be translated for the female gender."
1151
+ ];
1145
1152
  return terms.forEach(({ from, to }) => {
1146
1153
  instructions.push(`"${from}" -> "${to}"`);
1147
1154
  }), instructions.join(`
@@ -1807,6 +1814,7 @@ const setupTranslationJobStatuses = (dispatch, sourceDocuments, targetLanguages)
1807
1814
  references,
1808
1815
  shouldOverwriteFreshTranslations,
1809
1816
  maxConcurrentTranslationJobs: config.maxConcurrentTranslationJobs,
1817
+ maxReferenceDepth: config.maxReferenceDepth,
1810
1818
  shouldTranslateDiffs
1811
1819
  });
1812
1820
  },
@@ -1918,7 +1926,7 @@ const setupTranslationJobStatuses = (dispatch, sourceDocuments, targetLanguages)
1918
1926
  }
1919
1927
  return result;
1920
1928
  }, ReferenceConfigPanel = () => {
1921
- const { dispatch, document, shouldTranslateReferences, maxReferenceDepth, config, references } = useTranslationContext(), client = useClient({ apiVersion: "vX" }), [isLoadingReferences, setIsLoadingReferences] = useState(!1);
1929
+ const { dispatch, document, shouldTranslateReferences, maxReferenceDepth, config, references } = useTranslationContext(), client = useClient({ apiVersion: "vX" }), [isLoadingReferences, setIsLoadingReferences] = useState(!1), maxDepth = config.maxReferenceDepth || 3;
1922
1930
  useEffect(() => {
1923
1931
  (async () => {
1924
1932
  if (setIsLoadingReferences(!0), !shouldTranslateReferences) {
@@ -1976,18 +1984,14 @@ const setupTranslationJobStatuses = (dispatch, sourceDocuments, targetLanguages)
1976
1984
  ),
1977
1985
  shouldTranslateReferences ? /* @__PURE__ */ jsxs(Inline, { space: 2, children: [
1978
1986
  /* @__PURE__ */ jsx(Text, { children: "Max Depth:" }),
1979
- /* @__PURE__ */ jsxs(
1987
+ /* @__PURE__ */ jsx(
1980
1988
  Select,
1981
1989
  {
1982
1990
  disabled: !shouldTranslateReferences,
1983
1991
  placeholder: "Depth",
1984
1992
  onChange: handleMaxReferenceDepthChange,
1985
1993
  value: maxReferenceDepth.toString(),
1986
- children: [
1987
- /* @__PURE__ */ jsx("option", { value: 1, children: "1" }),
1988
- /* @__PURE__ */ jsx("option", { value: 2, children: "2" }),
1989
- /* @__PURE__ */ jsx("option", { value: 3, children: "3" })
1990
- ]
1994
+ children: Array.from({ length: maxDepth }, (_, i) => i + 1).map((depth) => /* @__PURE__ */ jsx("option", { value: depth.toString(), children: depth }, depth))
1991
1995
  }
1992
1996
  )
1993
1997
  ] }) : null
@@ -2197,7 +2201,7 @@ const setupTranslationJobStatuses = (dispatch, sourceDocuments, targetLanguages)
2197
2201
  documentType: document?._type,
2198
2202
  translatableTypes: config.translatableSchemaTypes
2199
2203
  }), null) : config ? {
2200
- label: "Translate!",
2204
+ label: "Translate",
2201
2205
  icon: TranslateIcon,
2202
2206
  onHandle: () => {
2203
2207
  devLog.info("Translation dialog opened", {