@sanity/assist 1.2.16 → 2.0.1

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 (52) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +551 -30
  3. package/dist/index.cjs.mjs +1 -0
  4. package/dist/index.d.ts +333 -9
  5. package/dist/index.esm.js +2463 -390
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/index.js +2457 -383
  8. package/dist/index.js.map +1 -1
  9. package/package.json +12 -11
  10. package/src/_lib/form/DocumentForm.tsx +2 -1
  11. package/src/_lib/form/constants.ts +1 -0
  12. package/src/assistDocument/AssistDocumentInput.tsx +24 -4
  13. package/src/assistDocument/RequestRunInstructionProvider.tsx +37 -21
  14. package/src/assistDocument/components/AssistDocumentForm.tsx +65 -21
  15. package/src/assistDocument/components/instruction/InstructionInput.tsx +5 -4
  16. package/src/assistDocument/components/instruction/InstructionOutputField.tsx +45 -0
  17. package/src/assistDocument/components/instruction/InstructionOutputInput.tsx +205 -0
  18. package/src/assistDocument/hooks/useStudioAssistDocument.ts +5 -32
  19. package/src/assistFormComponents/AssistField.tsx +11 -5
  20. package/src/assistFormComponents/AssistFormBlock.tsx +2 -3
  21. package/src/assistFormComponents/validation/listItem.tsx +2 -2
  22. package/src/assistInspector/AssistInspector.tsx +6 -0
  23. package/src/assistInspector/FieldAutocomplete.tsx +1 -0
  24. package/src/assistInspector/helpers.ts +9 -11
  25. package/src/assistLayout/AssistLayout.tsx +9 -9
  26. package/src/components/ImageContext.tsx +30 -13
  27. package/src/components/SafeValueInput.tsx +4 -1
  28. package/src/fieldActions/assistFieldActions.tsx +42 -13
  29. package/src/fieldActions/generateCaptionActions.tsx +17 -6
  30. package/src/fieldActions/generateImageActions.tsx +57 -0
  31. package/src/helpers/assistSupported.ts +10 -16
  32. package/src/helpers/conditionalMembers.test.ts +200 -0
  33. package/src/helpers/conditionalMembers.ts +127 -0
  34. package/src/helpers/misc.ts +8 -4
  35. package/src/helpers/typeUtils.ts +19 -5
  36. package/src/index.ts +3 -0
  37. package/src/plugin.tsx +18 -4
  38. package/src/schemas/assistDocumentSchema.tsx +40 -1
  39. package/src/schemas/serialize/serializeSchema.test.ts +239 -8
  40. package/src/schemas/serialize/serializeSchema.ts +77 -10
  41. package/src/schemas/typeDefExtensions.ts +89 -5
  42. package/src/translate/FieldTranslationProvider.tsx +360 -0
  43. package/src/translate/getLanguageParams.ts +26 -0
  44. package/src/translate/languageStore.ts +18 -0
  45. package/src/translate/paths.test.ts +133 -0
  46. package/src/translate/paths.ts +175 -0
  47. package/src/translate/translateActions.tsx +188 -0
  48. package/src/translate/types.ts +160 -0
  49. package/src/types.ts +67 -15
  50. package/src/useApiClient.ts +134 -2
  51. package/src/assistLayout/AlphaMigration.tsx +0 -310
  52. package/src/legacy-types.ts +0 -72
package/dist/index.esm.js CHANGED
@@ -1,14 +1,14 @@
1
1
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
- import { useClient, typed, useSchema, useDocumentStore, useDocumentPresence, createPatchChannel, FormBuilder, fromMutationPatches, pathToString, isObjectSchemaType, stringToPath, isKeySegment, useEditState, useCurrentUser, useValidationStatus, StatusButton, FormFieldHeaderText, PatchEvent, unset, set, useFormCallbacks, FormCallbacksProvider, FormInput, setIfMissing, insert, PresenceOverlay, VirtualizerScrollInstanceProvider, useColorSchemeValue, isArraySchemaType, ObjectInputMember, defineType, defineField, defineArrayMember, getPublishedId, useSyncState, definePlugin } from 'sanity';
3
- import { Card, Stack, Box, Button, Spinner, Flex, Label, focusFirstDescendant, Text, useClickOutside, Popover, useLayer, useGlobalKeyDown, useToast, Dialog, Tooltip, TextArea, Container, Autocomplete, Breadcrumbs, Badge, useTheme, rgba, ThemeProvider, ErrorBoundary, Switch, MenuButton, Menu, MenuItem } from '@sanity/ui';
2
+ import { useClient, isArraySchemaType, typed, useSchema, isKeySegment, isDocumentSchemaType, pathToString, useDocumentStore, useDocumentPresence, createPatchChannel, FormBuilder, fromMutationPatches, isObjectSchemaType, stringToPath as stringToPath$2, useEditState, useCurrentUser, StatusButton, FormFieldHeaderText, PatchEvent, unset, set, useFormCallbacks, FormCallbacksProvider, FormInput, setIfMissing, insert, PresenceOverlay, VirtualizerScrollInstanceProvider, useColorSchemeValue, ObjectInputMember, defineType, defineField, defineArrayMember, isArrayOfObjectsSchemaType, getPublishedId, useSyncState, definePlugin } from 'sanity';
3
+ import { Card, Stack, Box, Button, Spinner, Flex, Label, focusFirstDescendant, Text, useClickOutside, Popover, useLayer, useGlobalKeyDown, useToast, Dialog, Tooltip, TextArea, Container, Autocomplete, Breadcrumbs, Badge, useTheme, rgba, Checkbox, Radio, ThemeProvider, ErrorBoundary, Switch, MenuButton, Menu, MenuItem } from '@sanity/ui';
4
4
  import { useState, useRef, useEffect, useMemo, useCallback, createContext, useReducer, forwardRef, createElement, useContext, useId } from 'react';
5
- import { SyncIcon, DocumentIcon, LinkIcon, ImageIcon, BlockContentIcon, OlistIcon, BlockquoteIcon, StringIcon, ErrorOutlineIcon, CheckmarkCircleIcon, CloseCircleIcon, ClockIcon, PlayIcon, SparklesIcon, ArrowLeftIcon, SearchIcon, RetryIcon, ArrowRightIcon, CloseIcon, CheckmarkIcon, icons, TokenIcon, DocumentTextIcon, ThListIcon, CodeIcon, ComposeIcon, LockIcon, ControlsIcon } from '@sanity/icons';
5
+ import { SyncIcon, DocumentIcon, LinkIcon, ImageIcon, BlockContentIcon, OlistIcon, BlockquoteIcon, StringIcon, ErrorOutlineIcon, CheckmarkCircleIcon, CloseCircleIcon, ClockIcon, PlayIcon, SparklesIcon, ArrowLeftIcon, SearchIcon, RetryIcon, ArrowRightIcon, CloseIcon, CheckmarkIcon, icons, TokenIcon, DocumentTextIcon, ThListIcon, CodeIcon, ComposeIcon, LockIcon, TranslateIcon, ControlsIcon } from '@sanity/icons';
6
6
  import { mergeMap, share, take, filter, distinctUntilChanged, catchError, tap } from 'rxjs/operators';
7
7
  import isEqual from 'react-fast-compare';
8
8
  import { throwError, of, partition, merge, switchMap, delay, defer } from 'rxjs';
9
9
  import { exhaustMapToWithTrailing } from 'rxjs-exhaustmap-with-trailing';
10
- import { useDocumentPane, usePaneRouter, DocumentInspectorHeader, DocumentPaneProvider } from 'sanity/desk';
11
10
  import { extractWithPath } from '@sanity/mutator';
11
+ import { useDocumentPane, usePaneRouter, DocumentInspectorHeader, DocumentPaneProvider } from 'sanity/desk';
12
12
  import styled, { keyframes } from 'styled-components';
13
13
  import { minutesToMilliseconds, isAfter, addSeconds } from 'date-fns';
14
14
  import formatDistanceToNow from 'date-fns/formatDistanceToNow';
@@ -28,6 +28,8 @@ const instructionTaskTypeName = "sanity.assist.instructionTask";
28
28
  const fieldPresenceTypeName = "sanity.assist.instructionTask.presence";
29
29
  const assistSerializedTypeName = "sanity.assist.serialized.type";
30
30
  const assistSerializedFieldTypeName = "sanity.assist.serialized.field";
31
+ const outputFieldTypeName = "sanity.assist.output.field";
32
+ const outputTypeTypeName = "sanity.assist.output.type";
31
33
  const fieldPathParam = "pathKey";
32
34
  const instructionParam = "instruction";
33
35
  const documentRootKey = "<document>";
@@ -124,49 +126,59 @@ function isType(schemaType, typeName) {
124
126
  function isImage(schemaType) {
125
127
  return isType(schemaType, "image");
126
128
  }
127
- function getCaptionFieldOption(schemaType) {
128
- var _a;
129
+ function getDescriptionFieldOption(schemaType) {
130
+ var _a, _b;
131
+ if (!schemaType) {
132
+ return void 0;
133
+ }
134
+ const descriptionField = (_b = (_a = schemaType.options) == null ? void 0 : _a.aiAssist) == null ? void 0 : _b.imageDescriptionField;
135
+ if (descriptionField) {
136
+ return descriptionField;
137
+ }
138
+ return getDescriptionFieldOption(schemaType.type);
139
+ }
140
+ function getImageInstructionFieldOption(schemaType) {
141
+ var _a, _b;
129
142
  if (!schemaType) {
130
143
  return void 0;
131
144
  }
132
- const captionField = (_a = schemaType.options) == null ? void 0 : _a.captionField;
133
- if (captionField) {
134
- return captionField;
145
+ const imageInstructionField = (_b = (_a = schemaType.options) == null ? void 0 : _a.aiAssist) == null ? void 0 : _b.imageInstructionField;
146
+ if (imageInstructionField) {
147
+ return imageInstructionField;
135
148
  }
136
- return getCaptionFieldOption(schemaType.type);
149
+ return getImageInstructionFieldOption(schemaType.type);
137
150
  }
138
151
  function isSchemaAssistEnabled(type) {
139
152
  var _a, _b;
140
- return !((_b = (_a = type.options) == null ? void 0 : _a.aiWritingAssistance) == null ? void 0 : _b.exclude);
153
+ return !((_b = (_a = type.options) == null ? void 0 : _a.aiAssist) == null ? void 0 : _b.exclude);
141
154
  }
142
155
  function isAssistSupported(type) {
143
- let allowReadonlyHidden = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
144
156
  if (!isSchemaAssistEnabled(type)) {
145
157
  return false;
146
158
  }
147
- if (isDisabled(type, allowReadonlyHidden)) {
159
+ if (isDisabled(type)) {
148
160
  return false;
149
161
  }
150
162
  if (type.jsonType === "array") {
151
- const unsupportedArray = type.of.every(t => isDisabled(t, allowReadonlyHidden));
163
+ const unsupportedArray = type.of.every(t => isDisabled(t));
152
164
  return !unsupportedArray;
153
165
  }
154
166
  if (type.jsonType === "object") {
155
- const unsupportedObject = type.fields.every(field => isDisabled(field.type, allowReadonlyHidden));
167
+ const unsupportedObject = type.fields.every(field => isDisabled(field.type));
156
168
  return !unsupportedObject;
157
169
  }
158
170
  return true;
159
171
  }
160
- function isDisabled(type, allowReadonlyHidden) {
161
- const readonlyHidden = !!type.readOnly || !!type.hidden;
162
- return !isSchemaAssistEnabled(type) || isUnsupportedType(type) || !allowReadonlyHidden && readonlyHidden;
172
+ function isDisabled(type) {
173
+ return !isSchemaAssistEnabled(type) || isUnsupportedType(type);
163
174
  }
164
175
  function isUnsupportedType(type) {
165
- return type.jsonType === "number" || type.name === "sanity.imageCrop" || type.name === "sanity.imageHotspot" || isType(type, "reference") || isType(type, "crossDatasetReference") || isType(type, "slug") || isType(type, "url") || isType(type, "date") || isType(type, "datetime") || isType(type, "file");
176
+ var _a, _b;
177
+ return type.jsonType === "number" || type.name === "sanity.imageCrop" || type.name === "sanity.imageHotspot" || isType(type, "reference") && !((_b = (_a = type == null ? void 0 : type.options) == null ? void 0 : _a.aiAssist) == null ? void 0 : _b.embeddingsIndex) || isType(type, "crossDatasetReference") || isType(type, "slug") || isType(type, "url") || isType(type, "date") || isType(type, "datetime") || isType(type, "file");
166
178
  }
167
179
  const inlineTypes = ["document", "object", "image", "file"];
168
180
  function serializeSchema(schema, options) {
169
- const list = schema.getTypeNames().filter(t => !(hiddenTypes.includes(t) || t.startsWith("sanity."))).map(t => schema.get(t)).filter(t => !!t).filter(t => !t.hidden && !t.readOnly).map(t => getSchemaStub(t, schema, options)).filter(t => {
181
+ const list = schema.getTypeNames().filter(t => !(hiddenTypes.includes(t) || t.startsWith("sanity."))).map(t => schema.get(t)).filter(t => !!t).map(t => getSchemaStub(t, schema, options)).filter(t => {
170
182
  if ("to" in t && t.to && !t.to.length) {
171
183
  return false;
172
184
  }
@@ -204,26 +216,41 @@ function getSchemaStub(schemaType, schema, options) {
204
216
  return removeUndef(baseSchema);
205
217
  }
206
218
  function getBaseFields(schema, type, typeName, options) {
207
- var _a, _b, _c;
208
- const imagePromptField = (_a = type.options) == null ? void 0 : _a.imagePromptField;
219
+ var _a, _b, _c, _d, _e, _f;
220
+ const schemaOptions = removeUndef({
221
+ imagePromptField: (_b = (_a = type.options) == null ? void 0 : _a.aiAssist) == null ? void 0 : _b.imageInstructionField,
222
+ embeddingsIndex: (_d = (_c = type.options) == null ? void 0 : _c.aiAssist) == null ? void 0 : _d.embeddingsIndex
223
+ });
209
224
  return removeUndef({
210
- options: imagePromptField ? {
211
- imagePromptField
212
- } : void 0,
213
- values: Array.isArray((_b = type == null ? void 0 : type.options) == null ? void 0 : _b.list) ? (_c = type == null ? void 0 : type.options) == null ? void 0 : _c.list.map(v => {
225
+ options: Object.keys(schemaOptions).length ? schemaOptions : void 0,
226
+ values: Array.isArray((_e = type == null ? void 0 : type.options) == null ? void 0 : _e.list) ? (_f = type == null ? void 0 : type.options) == null ? void 0 : _f.list.map(v => {
214
227
  var _a2;
215
228
  return typeof v === "string" ? v : (_a2 = v.value) != null ? _a2 : "".concat(v.title);
216
229
  }) : void 0,
217
230
  of: "of" in type && typeName === "array" ? arrayOf(type, schema, options) : void 0,
218
231
  to: "to" in type && typeName === "reference" ? refToTypeNames(type) : void 0,
219
- fields: "fields" in type && inlineTypes.includes(typeName) ? serializeFields(schema, type, options) : void 0
232
+ fields: "fields" in type && inlineTypes.includes(typeName) ? serializeFields(schema, type, options) : void 0,
233
+ annotations: typeName === "block" && "fields" in type ? serializeAnnotations(type, schema, options) : void 0,
234
+ inlineOf: typeName === "block" && "fields" in type ? serializeInlineOf(type, schema, options) : void 0,
235
+ hidden: typeof type.hidden === "function" ? "function" : type.hidden ? true : void 0,
236
+ readOnly: typeof type.readOnly === "function" ? "function" : type.readOnly ? true : void 0
220
237
  });
221
238
  }
222
239
  function serializeFields(schema, schemaType, options) {
223
- return schemaType.fields.filter(f => {
240
+ const fields = schemaType.fieldsets ? schemaType.fieldsets.flatMap(fs => fs.single ? fs.field : fs.fields.map(f => ({
241
+ ...f,
242
+ type: {
243
+ ...f.type,
244
+ // if fieldset is (conditionally) hidden, the field must be considered the same way
245
+ // ie, if the field does not show up in conditionalMembers, it is hidden
246
+ // regardless of weather or not it is the field function or the fieldset function that hides it
247
+ hidden: typeof fs.hidden === "function" ? fs.hidden : fs.hidden ? true : f.type.hidden
248
+ }
249
+ }))) : schemaType.fields;
250
+ return fields.filter(f => {
224
251
  var _a, _b;
225
252
  return !["sanity.imageHotspot", "sanity.imageCrop"].includes((_b = (_a = f.type) == null ? void 0 : _a.name) != null ? _b : "");
226
- }).filter(f => isAssistSupported(f.type)).filter(f => !f.type.hidden && !f.type.readOnly).map(field => serializeMember(schema, field.type, field.name, options));
253
+ }).filter(f => isAssistSupported(f.type)).map(field => serializeMember(schema, field.type, field.name, options));
227
254
  }
228
255
  function serializeMember(schema, type, name, options) {
229
256
  var _a, _b;
@@ -239,6 +266,25 @@ function serializeMember(schema, type, name, options) {
239
266
  ...getBaseFields(schema, type, typeName, options)
240
267
  });
241
268
  }
269
+ function serializeInlineOf(blockSchemaType, schema, options) {
270
+ const childrenField = blockSchemaType.fields.find(f => f.name === "children");
271
+ const childrenType = childrenField == null ? void 0 : childrenField.type;
272
+ if (!childrenType || !isArraySchemaType(childrenType)) {
273
+ return void 0;
274
+ }
275
+ return arrayOf({
276
+ ...childrenType,
277
+ of: childrenType.of.filter(t => !isType(t, "span"))
278
+ }, schema, options);
279
+ }
280
+ function serializeAnnotations(blockSchemaType, schema, options) {
281
+ const markDefs = blockSchemaType.fields.find(f => f.name === "markDefs");
282
+ const marksType = markDefs == null ? void 0 : markDefs.type;
283
+ if (!marksType || !isArraySchemaType(marksType)) {
284
+ return void 0;
285
+ }
286
+ return arrayOf(marksType, schema, options);
287
+ }
242
288
  function arrayOf(arrayType, schema, options) {
243
289
  return arrayType.of.filter(type => isAssistSupported(type)).map(t => {
244
290
  return serializeMember(schema, t, t.name, options);
@@ -357,7 +403,111 @@ function SchemaEntry(_ref) {
357
403
  children: out
358
404
  });
359
405
  }
406
+ const MAX_DEPTH$1 = 6;
407
+ function getDocumentMembersFlat(doc, schemaType) {
408
+ if (!isDocumentSchemaType(schemaType)) {
409
+ console.error("Schema type is not a document");
410
+ return [];
411
+ }
412
+ return extractPaths(doc, schemaType, [], MAX_DEPTH$1);
413
+ }
414
+ function extractPaths(doc, schemaType, path, maxDepth) {
415
+ if (path.length >= maxDepth) {
416
+ return [];
417
+ }
418
+ return schemaType.fields.reduce((acc, field) => {
419
+ var _a, _b;
420
+ const fieldPath = [...path, field.name];
421
+ const fieldSchema = field.type;
422
+ const {
423
+ value
424
+ } = (_a = extractWithPath(pathToString(fieldPath), doc)[0]) != null ? _a : {};
425
+ if (!value) {
426
+ return acc;
427
+ }
428
+ const thisFieldWithPath = {
429
+ path: fieldPath,
430
+ name: field.name,
431
+ schemaType: fieldSchema,
432
+ value
433
+ };
434
+ if (fieldSchema.jsonType === "object") {
435
+ const innerFields = extractPaths(doc, fieldSchema, fieldPath, maxDepth);
436
+ return [...acc, thisFieldWithPath, ...innerFields];
437
+ } else if (fieldSchema.jsonType === "array" && fieldSchema.of.length && fieldSchema.of.some(item => "fields" in item)) {
438
+ const {
439
+ value: arrayValue
440
+ } = (_b = extractWithPath(pathToString(fieldPath), doc)[0]) != null ? _b : {};
441
+ let arrayPaths = [];
442
+ if (arrayValue == null ? void 0 : arrayValue.length) {
443
+ for (const item of arrayValue) {
444
+ const itemPath = [...fieldPath, {
445
+ _key: item._key
446
+ }];
447
+ let itemSchema = fieldSchema.of.find(t => t.name === item._type);
448
+ if (!item._type) {
449
+ itemSchema = fieldSchema.of[0];
450
+ console.warn("Array item is missing _type - using the first defined type in the array.of schema", {
451
+ itemPath,
452
+ item,
453
+ itemSchema
454
+ });
455
+ }
456
+ if (item._key && itemSchema) {
457
+ const innerFields = extractPaths(doc, itemSchema, itemPath, maxDepth);
458
+ const arrayMember = {
459
+ path: itemPath,
460
+ name: item._key,
461
+ schemaType: itemSchema,
462
+ value: item
463
+ };
464
+ arrayPaths = [...arrayPaths, arrayMember, ...innerFields];
465
+ }
466
+ }
467
+ }
468
+ return [...acc, thisFieldWithPath, ...arrayPaths];
469
+ }
470
+ return [...acc, thisFieldWithPath];
471
+ }, []);
472
+ }
473
+ const defaultLanguageOutputs = function (member, enclosingType, translateFromLanguageId, translateToLanguageIds) {
474
+ if (member.schemaType.jsonType === "object" && member.schemaType.name.startsWith("internationalizedArray")) {
475
+ const pathEnd = member.path.slice(-1);
476
+ const language = isKeySegment(pathEnd[0]) ? pathEnd[0]._key : null;
477
+ return language === translateFromLanguageId ? translateToLanguageIds.map(translateToId => ({
478
+ id: translateToId,
479
+ outputPath: [...member.path.slice(0, -1), {
480
+ _key: translateToId
481
+ }]
482
+ })) : void 0;
483
+ }
484
+ if (enclosingType.jsonType === "object" && enclosingType.name.startsWith("locale")) {
485
+ return translateFromLanguageId === member.name ? translateToLanguageIds.map(translateToId => ({
486
+ id: translateToId,
487
+ outputPath: [...member.path.slice(0, -1), translateToId]
488
+ })) : void 0;
489
+ }
490
+ return void 0;
491
+ };
492
+ function getFieldLanguageMap(documentSchema, documentMembers, translateFromLanguageId, outputLanguageIds, langFn) {
493
+ var _a, _b, _c;
494
+ const translationMaps = [];
495
+ for (const member of documentMembers) {
496
+ const parentPath = member.path.slice(0, -1);
497
+ const enclosingType = (_b = (_a = documentMembers.find(m => pathToString(m.path) === pathToString(parentPath))) == null ? void 0 : _a.schemaType) != null ? _b : documentSchema;
498
+ const translations = (_c = langFn(member, enclosingType, translateFromLanguageId, outputLanguageIds)) == null ? void 0 : _c.filter(translation => translation.id !== translateFromLanguageId);
499
+ if (translations) {
500
+ translationMaps.push({
501
+ inputLanguageId: translateFromLanguageId,
502
+ inputPath: member.path,
503
+ outputs: translations
504
+ });
505
+ }
506
+ }
507
+ return translationMaps;
508
+ }
360
509
  const aiInspectorId = "ai-assistance";
510
+ const assistFormId = "assist";
361
511
  const preventDefault = ev => ev.preventDefault();
362
512
  function DocumentForm(props) {
363
513
  var _a;
@@ -453,7 +603,7 @@ function DocumentForm(props) {
453
603
  changed: formState.changed,
454
604
  focused: formState.focused,
455
605
  groups: formState.groups,
456
- id: "root",
606
+ id: assistFormId,
457
607
  members: formState.members,
458
608
  onChange,
459
609
  onFieldGroupSelect: onSetActiveFieldGroup,
@@ -551,7 +701,7 @@ function getFieldRefs(schemaType, parent) {
551
701
  };
552
702
  const fields = field.type.jsonType === "object" ? getFieldRefs(field.type, fieldRef, depth + 1) : [];
553
703
  const syntheticFields = field.type.jsonType === "array" ? getSyntheticFields(field.type, fieldRef, depth + 1) : [];
554
- if (!isAssistSupported(field.type, true)) {
704
+ if (!isAssistSupported(field.type)) {
555
705
  return [...fields, ...syntheticFields];
556
706
  }
557
707
  return [fieldRef, ...fields, ...syntheticFields];
@@ -578,7 +728,7 @@ function getSyntheticFields(schemaType, parent) {
578
728
  synthetic: true
579
729
  };
580
730
  const fields = itemType.jsonType === "object" ? getFieldRefs(itemType, fieldRef, depth + 1) : [];
581
- if (!isAssistSupported(itemType, true)) {
731
+ if (!isAssistSupported(itemType)) {
582
732
  return fields;
583
733
  }
584
734
  return [fieldRef, ...fields];
@@ -588,7 +738,7 @@ function getTypePath(doc, pathString) {
588
738
  if (!pathString) {
589
739
  return void 0;
590
740
  }
591
- const path = stringToPath(pathString);
741
+ const path = stringToPath$2(pathString);
592
742
  const currentPath = [];
593
743
  let valid = true;
594
744
  const syntheticPath = path.map(segment => {
@@ -667,7 +817,6 @@ function useStudioAssistDocument(_ref2) {
667
817
  } = _ref2;
668
818
  const documentTypeName = schemaType.name;
669
819
  const currentUser = useCurrentUser();
670
- const validation = useValidationStatus(publicId(documentId), schemaType.name).validation;
671
820
  const assistDocument = useDocumentState(assistDocumentId(documentTypeName), assistDocumentTypeName);
672
821
  const assistTasksStatus = useDocumentState(assistTasksStatusId(documentId != null ? documentId : ""), assistTasksStatusTypeName);
673
822
  const client = useClient({
@@ -692,7 +841,7 @@ function useStudioAssistDocument(_ref2) {
692
841
  return {
693
842
  ...assistField,
694
843
  tasks: tasks.filter(task => task.path === assistField.path),
695
- instructions: (_a2 = assistField.instructions) == null ? void 0 : _a2.filter(p => !p.userId || p.userId === (currentUser == null ? void 0 : currentUser.id)).map(instruction => asStudioInstruction(instruction, tasks, validation))
844
+ instructions: (_a2 = assistField.instructions) == null ? void 0 : _a2.filter(p => !p.userId || p.userId === (currentUser == null ? void 0 : currentUser.id)).map(instruction => asStudioInstruction(instruction, tasks))
696
845
  };
697
846
  });
698
847
  return typed({
@@ -707,21 +856,12 @@ function useStudioAssistDocument(_ref2) {
707
856
  }),
708
857
  fields
709
858
  });
710
- }, [assistDocument, assistTasksStatus, currentUser, validation]);
859
+ }, [assistDocument, assistTasksStatus, currentUser]);
711
860
  }
712
- function asStudioInstruction(instruction, run, validation) {
713
- var _a;
714
- const errors = validation.filter(marker => marker.level === "error");
715
- const fieldRefs = ((_a = instruction == null ? void 0 : instruction.prompt) != null ? _a : []).flatMap(block => {
716
- if (block._type === "block") {
717
- return block.children.filter(c => c._type === fieldReferenceTypeName);
718
- }
719
- return [];
720
- });
861
+ function asStudioInstruction(instruction, run) {
721
862
  return {
722
863
  ...instruction,
723
- tasks: run.filter(task => task.instructionKey === instruction._key).filter(task => task.started && ( /* @__PURE__ */new Date()).getTime() - new Date(task.started).getTime() < maxHistoryVisibilityMs),
724
- validation: errors.filter(marker => fieldRefs.map(r => r.path).filter(p => !!p).find(path => pathToString(marker.path) === path))
864
+ tasks: run.filter(task => task.instructionKey === instruction._key).filter(task => task.started && ( /* @__PURE__ */new Date()).getTime() - new Date(task.started).getTime() < maxHistoryVisibilityMs)
725
865
  };
726
866
  }
727
867
  function useInterval(ms) {
@@ -745,12 +885,15 @@ function TimeAgo(_ref3) {
745
885
  }
746
886
  function usePathKey(path) {
747
887
  return useMemo(() => {
748
- if (path.length) {
749
- return Array.isArray(path) ? pathToString(path) : path;
750
- }
751
- return documentRootKey;
888
+ return getPathKey(path);
752
889
  }, [path]);
753
890
  }
891
+ function getPathKey(path) {
892
+ if (path.length) {
893
+ return Array.isArray(path) ? pathToString(path) : path;
894
+ }
895
+ return documentRootKey;
896
+ }
754
897
  function getInstructionTitle(instruction) {
755
898
  var _a;
756
899
  return (_a = instruction == null ? void 0 : instruction.title) != null ? _a : "Untitled";
@@ -959,12 +1102,63 @@ function TaskItem(props) {
959
1102
  });
960
1103
  }
961
1104
  const basePath = "/assist/tasks/instruction";
1105
+ function canUseAssist(status) {
1106
+ return (status == null ? void 0 : status.enabled) && status.initialized && status.validToken;
1107
+ }
962
1108
  function useApiClient(customApiClient) {
963
1109
  const client = useClient({
964
1110
  apiVersion: "2023-06-05"
965
1111
  });
966
1112
  return useMemo(() => customApiClient ? customApiClient(client) : client, [client, customApiClient]);
967
1113
  }
1114
+ function useTranslate(apiClient) {
1115
+ const [loading, setLoading] = useState(false);
1116
+ const user = useCurrentUser();
1117
+ const schema = useSchema();
1118
+ const types = useMemo(() => serializeSchema(schema, {
1119
+ leanFormat: true
1120
+ }), [schema]);
1121
+ const toast = useToast();
1122
+ const translate = useCallback(_ref4 => {
1123
+ let {
1124
+ documentId,
1125
+ languagePath,
1126
+ translatePath,
1127
+ fieldLanguageMap,
1128
+ conditionalMembers
1129
+ } = _ref4;
1130
+ setLoading(true);
1131
+ return apiClient.request({
1132
+ method: "POST",
1133
+ url: "/assist/tasks/translate/".concat(apiClient.config().dataset, "?projectId=").concat(apiClient.config().projectId),
1134
+ body: {
1135
+ documentId,
1136
+ types,
1137
+ languagePath,
1138
+ fieldLanguageMap,
1139
+ conditionalMembers,
1140
+ translatePath: translatePath.length === 0 ? documentRootKey : pathToString(translatePath),
1141
+ userId: user == null ? void 0 : user.id
1142
+ }
1143
+ }).catch(e => {
1144
+ toast.push({
1145
+ status: "error",
1146
+ title: "Translate failed",
1147
+ description: e.message
1148
+ });
1149
+ setLoading(false);
1150
+ throw e;
1151
+ }).finally(() => {
1152
+ setTimeout(() => {
1153
+ setLoading(false);
1154
+ }, 2e3);
1155
+ });
1156
+ }, [setLoading, apiClient, toast, user, types]);
1157
+ return useMemo(() => ({
1158
+ translate,
1159
+ loading
1160
+ }), [translate, loading]);
1161
+ }
968
1162
  function useGenerateCaption(apiClient) {
969
1163
  const [loading, setLoading] = useState(false);
970
1164
  const user = useCurrentUser();
@@ -973,11 +1167,11 @@ function useGenerateCaption(apiClient) {
973
1167
  leanFormat: true
974
1168
  }), [schema]);
975
1169
  const toast = useToast();
976
- const generateCaption = useCallback(_ref4 => {
1170
+ const generateCaption = useCallback(_ref5 => {
977
1171
  let {
978
1172
  path,
979
1173
  documentId
980
- } = _ref4;
1174
+ } = _ref5;
981
1175
  setLoading(true);
982
1176
  return apiClient.request({
983
1177
  method: "POST",
@@ -991,7 +1185,7 @@ function useGenerateCaption(apiClient) {
991
1185
  }).catch(e => {
992
1186
  toast.push({
993
1187
  status: "error",
994
- title: "Generate caption failed",
1188
+ title: "Generate image description failed",
995
1189
  description: e.message
996
1190
  });
997
1191
  setLoading(false);
@@ -1007,6 +1201,48 @@ function useGenerateCaption(apiClient) {
1007
1201
  loading
1008
1202
  }), [generateCaption, loading]);
1009
1203
  }
1204
+ function useGenerateImage(apiClient) {
1205
+ const [loading, setLoading] = useState(false);
1206
+ const user = useCurrentUser();
1207
+ const schema = useSchema();
1208
+ const types = useMemo(() => serializeSchema(schema, {
1209
+ leanFormat: true
1210
+ }), [schema]);
1211
+ const toast = useToast();
1212
+ const generateImage = useCallback(_ref6 => {
1213
+ let {
1214
+ path,
1215
+ documentId
1216
+ } = _ref6;
1217
+ setLoading(true);
1218
+ return apiClient.request({
1219
+ method: "POST",
1220
+ url: "/assist/tasks/generate-image/".concat(apiClient.config().dataset, "?projectId=").concat(apiClient.config().projectId),
1221
+ body: {
1222
+ path,
1223
+ documentId,
1224
+ types,
1225
+ userId: user == null ? void 0 : user.id
1226
+ }
1227
+ }).catch(e => {
1228
+ toast.push({
1229
+ status: "error",
1230
+ title: "Generate image from prompt failed",
1231
+ description: e.message
1232
+ });
1233
+ setLoading(false);
1234
+ throw e;
1235
+ }).finally(() => {
1236
+ setTimeout(() => {
1237
+ setLoading(false);
1238
+ }, 2e3);
1239
+ });
1240
+ }, [setLoading, apiClient, toast, user, types]);
1241
+ return useMemo(() => ({
1242
+ generateImage,
1243
+ loading
1244
+ }), [generateImage, loading]);
1245
+ }
1010
1246
  function useGetInstructStatus(apiClient) {
1011
1247
  const [loading, setLoading] = useState(true);
1012
1248
  const getInstructStatus = useCallback(async () => {
@@ -1196,8 +1432,8 @@ function RunInstructionProvider(props) {
1196
1432
  runInstructionRequest({
1197
1433
  ...request,
1198
1434
  instructionKey: instruction._key,
1199
- userTexts: Object.entries(inputs).map(_ref5 => {
1200
- let [key, value] = _ref5;
1435
+ userTexts: Object.entries(inputs).map(_ref7 => {
1436
+ let [key, value] = _ref7;
1201
1437
  return {
1202
1438
  blockKey: key,
1203
1439
  userInput: value
@@ -1210,8 +1446,8 @@ function RunInstructionProvider(props) {
1210
1446
  const open = !!runRequest;
1211
1447
  const runDisabled = useMemo(() => {
1212
1448
  var _a2, _b;
1213
- return ((_b = (_a2 = runRequest == null ? void 0 : runRequest.userInputBlocks) == null ? void 0 : _a2.length) != null ? _b : 0) > Object.entries(inputs).filter(_ref6 => {
1214
- let [, value] = _ref6;
1449
+ return ((_b = (_a2 = runRequest == null ? void 0 : runRequest.userInputBlocks) == null ? void 0 : _a2.length) != null ? _b : 0) > Object.entries(inputs).filter(_ref8 => {
1450
+ let [, value] = _ref8;
1215
1451
  return !!value;
1216
1452
  }).length;
1217
1453
  }, [runRequest == null ? void 0 : runRequest.userInputBlocks, inputs]);
@@ -1322,29 +1558,37 @@ function getAssistableDocId(documentSchemaType, documentId) {
1322
1558
  return documentSchemaType.liveEdit ? baseId : "drafts.".concat(baseId);
1323
1559
  }
1324
1560
  function useRequestRunInstruction(args) {
1325
- const {
1326
- documentOnChange,
1327
- isDocAssistable: isDocAssistable2
1328
- } = args;
1329
1561
  const {
1330
1562
  runInstruction,
1331
1563
  instructionLoading
1332
1564
  } = useRunInstruction();
1333
- const [queuedTask, setQueuedTask] = useState(void 0);
1334
- useEffect(() => {
1335
- if (queuedTask && isDocAssistable2) {
1336
- runInstruction(queuedTask);
1337
- setQueuedTask(void 0);
1338
- }
1339
- }, [queuedTask, isDocAssistable2, runInstruction]);
1565
+ const requestRunInstruction = useDraftDelayedTask({
1566
+ ...args,
1567
+ task: runInstruction
1568
+ });
1340
1569
  return {
1341
1570
  instructionLoading,
1342
- requestRunInstruction: useCallback(task => {
1343
- documentOnChange(PatchEvent.from([unset(["_force_document_creation"])]));
1344
- setQueuedTask(task);
1345
- }, [setQueuedTask, documentOnChange])
1571
+ requestRunInstruction
1346
1572
  };
1347
1573
  }
1574
+ function useDraftDelayedTask(args) {
1575
+ const {
1576
+ documentOnChange,
1577
+ isDocAssistable: isDocAssistable2,
1578
+ task
1579
+ } = args;
1580
+ const [queuedArgs, setQueuedArgs] = useState(void 0);
1581
+ useEffect(() => {
1582
+ if (queuedArgs && isDocAssistable2) {
1583
+ task(queuedArgs);
1584
+ setQueuedArgs(void 0);
1585
+ }
1586
+ }, [queuedArgs, isDocAssistable2, task]);
1587
+ return useCallback(taskArgs => {
1588
+ documentOnChange(PatchEvent.from([unset(["_force_document_creation"])]));
1589
+ setQueuedArgs(taskArgs);
1590
+ }, [setQueuedArgs, documentOnChange]);
1591
+ }
1348
1592
  const SparklesIllustration = styled(SparklesIcon)({
1349
1593
  fontSize: "3.125em",
1350
1594
  "& path": {
@@ -1519,7 +1763,6 @@ function AssistDocumentFormEditable(props) {
1519
1763
  onChange(set((_a = documentSchema.title) != null ? _a : documentSchema.name, ["title"]));
1520
1764
  }
1521
1765
  }, [title, documentSchema, onChange, id]);
1522
- const fieldExists = !!(fields == null ? void 0 : fields.some(f => f._key === typePath));
1523
1766
  const {
1524
1767
  onPathOpen,
1525
1768
  ...formCallbacks
@@ -1551,7 +1794,8 @@ function AssistDocumentFormEditable(props) {
1551
1794
  children: [/* @__PURE__ */jsx(FieldsInitializer, {
1552
1795
  pathKey: typePath,
1553
1796
  activePath,
1554
- fieldExists,
1797
+ fields,
1798
+ documentSchema,
1555
1799
  onChange
1556
1800
  }, typePath), instruction && /* @__PURE__ */jsx(BackToInstructionListLink, {}), activePath && /* @__PURE__ */jsx(FormCallbacksProvider, {
1557
1801
  ...newCallbacks,
@@ -1576,7 +1820,7 @@ function useSelectedSchema(fieldPath, documentSchema) {
1576
1820
  if (fieldPath === documentRootKey) {
1577
1821
  return documentSchema;
1578
1822
  }
1579
- const path = stringToPath(fieldPath);
1823
+ const path = stringToPath$2(fieldPath);
1580
1824
  let currentSchema = documentSchema;
1581
1825
  for (let i = 0; i < path.length; i++) {
1582
1826
  const segment = path[i];
@@ -1595,25 +1839,64 @@ function useSelectedSchema(fieldPath, documentSchema) {
1595
1839
  return currentSchema;
1596
1840
  }, [documentSchema, fieldPath]);
1597
1841
  }
1598
- function FieldsInitializer(_ref7) {
1842
+ function FieldsInitializer(_ref9) {
1599
1843
  let {
1600
1844
  pathKey,
1601
1845
  activePath,
1602
- fieldExists,
1846
+ fields,
1847
+ documentSchema,
1603
1848
  onChange
1604
- } = _ref7;
1849
+ } = _ref9;
1850
+ const {
1851
+ config: {
1852
+ __presets: presets
1853
+ }
1854
+ } = useAiAssistanceConfig();
1855
+ const existingField = fields == null ? void 0 : fields.find(f => f._key === pathKey);
1856
+ const documentPresets = !!(documentSchema == null ? void 0 : documentSchema.name) && (presets == null ? void 0 : presets[documentSchema == null ? void 0 : documentSchema.name]);
1857
+ const missingPresetInstructions = useMemo(() => {
1858
+ var _a, _b;
1859
+ if (!documentPresets || !pathKey) {
1860
+ return void 0;
1861
+ }
1862
+ const existingInstructions = existingField == null ? void 0 : existingField.instructions;
1863
+ const presetField = (_a = documentPresets.fields) == null ? void 0 : _a.find(f => f.path === pathKey);
1864
+ return (_b = presetField == null ? void 0 : presetField.instructions) == null ? void 0 : _b.filter(i => !(existingInstructions == null ? void 0 : existingInstructions.some(ei => ei._key === i._key)));
1865
+ }, [documentPresets, pathKey, existingField]);
1605
1866
  const initialized = useRef(false);
1606
1867
  useEffect(() => {
1607
- if (initialized.current || fieldExists || activePath || !pathKey) {
1868
+ if (initialized.current || !pathKey) {
1869
+ return;
1870
+ }
1871
+ if (existingField && !(missingPresetInstructions == null ? void 0 : missingPresetInstructions.length)) {
1608
1872
  return;
1609
1873
  }
1610
- onChange([setIfMissing([], ["fields"]), insert([typed({
1611
- _key: pathKey,
1612
- _type: assistFieldTypeName,
1613
- path: pathKey
1614
- })], "after", ["fields", -1])]);
1874
+ let event = PatchEvent.from([setIfMissing([], ["fields"])]);
1875
+ if (!existingField) {
1876
+ event = event.append(insert([typed({
1877
+ _key: pathKey,
1878
+ _type: assistFieldTypeName,
1879
+ path: pathKey
1880
+ })], "after", ["fields", -1]));
1881
+ }
1882
+ if (missingPresetInstructions == null ? void 0 : missingPresetInstructions.length) {
1883
+ event = event.append(insert(missingPresetInstructions.map(preset => {
1884
+ var _a;
1885
+ return {
1886
+ ...preset,
1887
+ _type: "sanity.assist.instruction",
1888
+ prompt: (_a = preset.prompt) == null ? void 0 : _a.map(p => ({
1889
+ markDefs: [],
1890
+ ...p
1891
+ }))
1892
+ };
1893
+ }), "after", ["fields", {
1894
+ _key: pathKey
1895
+ }, "instructions", -1]));
1896
+ }
1897
+ onChange(event);
1615
1898
  initialized.current = true;
1616
- }, [activePath, onChange, pathKey, fieldExists]);
1899
+ }, [activePath, onChange, pathKey, existingField, missingPresetInstructions]);
1617
1900
  return null;
1618
1901
  }
1619
1902
  function FieldAutocomplete(props) {
@@ -1632,7 +1915,7 @@ function FieldAutocomplete(props) {
1632
1915
  return getFieldRefs(schemaType);
1633
1916
  }, [schemaType, includeDocument]);
1634
1917
  const currentField = useMemo(() => fieldRefs.find(f => f.key === fieldPath), [fieldPath, fieldRefs]);
1635
- const autocompleteOptions = useMemo(() => fieldRefs.filter(field => filter ? filter(field) : true).map(field => ({
1918
+ const autocompleteOptions = useMemo(() => fieldRefs.filter(field => filter ? filter(field) : true).filter(f => !isType(f.schemaType, "reference")).map(field => ({
1636
1919
  value: field.key,
1637
1920
  field
1638
1921
  })), [fieldRefs, filter]);
@@ -1745,6 +2028,78 @@ function FieldTitle(props) {
1745
2028
  })
1746
2029
  });
1747
2030
  }
2031
+ const MAX_DEPTH = 8;
2032
+ function getConditionalMembers(docState) {
2033
+ const doc = {
2034
+ path: "",
2035
+ hidden: false,
2036
+ readOnly: !!docState.readOnly,
2037
+ conditional: typeof docState.schemaType.hidden === "function"
2038
+ };
2039
+ return [doc, ...extractConditionalPaths(docState, MAX_DEPTH)].filter(v => v.conditional).map(_ref10 => {
2040
+ let {
2041
+ conditional,
2042
+ ...state
2043
+ } = _ref10;
2044
+ return {
2045
+ ...state
2046
+ };
2047
+ });
2048
+ }
2049
+ function isConditional(schemaType) {
2050
+ return typeof schemaType.hidden === "function" || typeof schemaType.readOnly === "function";
2051
+ }
2052
+ function conditionalState(memberState) {
2053
+ return {
2054
+ path: pathToString(memberState.path),
2055
+ readOnly: !!memberState.readOnly,
2056
+ hidden: false,
2057
+ // if its in members, its not hidden
2058
+ conditional: isConditional(memberState.schemaType)
2059
+ };
2060
+ }
2061
+ function extractConditionalPaths(node, maxDepth) {
2062
+ if (node.path.length >= maxDepth) {
2063
+ return [];
2064
+ }
2065
+ return node.members.reduce((acc, member) => {
2066
+ var _a, _b;
2067
+ if (member.kind === "error") {
2068
+ return acc;
2069
+ }
2070
+ if (member.kind === "field") {
2071
+ const schemaType = member.field.schemaType;
2072
+ if (schemaType.jsonType === "object") {
2073
+ const innerFields = member.field.readOnly ? [] : extractConditionalPaths(member.field, maxDepth);
2074
+ return [...acc, conditionalState(member.field), ...innerFields];
2075
+ } else if (schemaType.jsonType === "array") {
2076
+ const array = member.field;
2077
+ let arrayPaths = [];
2078
+ const isObjectsArray = array.members.some(m => m.kind === "item" && isObjectSchemaType(m.item.schemaType));
2079
+ if (!array.readOnly) {
2080
+ for (const arrayMember of array.members) {
2081
+ if (arrayMember.kind === "error") {
2082
+ continue;
2083
+ }
2084
+ const innerFields = isObjectsArray && !arrayMember.item.readOnly ? extractConditionalPaths(arrayMember.item, maxDepth) : [];
2085
+ arrayPaths = [...arrayPaths, conditionalState(arrayMember.item), ...innerFields];
2086
+ }
2087
+ }
2088
+ return [...acc, conditionalState(array), ...arrayPaths];
2089
+ }
2090
+ return [...acc, conditionalState(member.field)];
2091
+ } else if (member.kind === "fieldSet") {
2092
+ const conditionalFieldset = !!((_b = (_a = node.schemaType) == null ? void 0 : _a.fieldsets) == null ? void 0 : _b.some(f => !f.single && f.name === member.fieldSet.name && typeof f.hidden === "function"));
2093
+ const innerFields = extractConditionalPaths(member.fieldSet, maxDepth).map(f => ({
2094
+ ...f,
2095
+ // if fieldset is conditional, visible fields must also be considered conditional
2096
+ conditional: conditionalFieldset != null ? conditionalFieldset : f.conditional
2097
+ }));
2098
+ return [...acc, ...innerFields];
2099
+ }
2100
+ return acc;
2101
+ }, []);
2102
+ }
1748
2103
  var __freeze$4 = Object.freeze;
1749
2104
  var __defProp$4 = Object.defineProperty;
1750
2105
  var __template$4 = (cooked, raw) => __freeze$4(__defProp$4(cooked, "raw", {
@@ -1884,12 +2239,15 @@ function AssistInspector(props) {
1884
2239
  documentType,
1885
2240
  value: docValue,
1886
2241
  schemaType,
1887
- onChange: documentOnChange
2242
+ onChange: documentOnChange,
2243
+ formState
1888
2244
  } = documentPane;
1889
2245
  const {
1890
2246
  published,
1891
2247
  draft
1892
2248
  } = useEditState(documentId, documentType, "low");
2249
+ const formStateRef = useRef(formState);
2250
+ formStateRef.current = formState;
1893
2251
  const assistableDocId = getAssistableDocId(schemaType, documentId);
1894
2252
  const {
1895
2253
  instructionLoading,
@@ -1943,7 +2301,8 @@ function AssistInspector(props) {
1943
2301
  path: pathKey,
1944
2302
  typePath,
1945
2303
  assistDocumentId: assistDocumentId(documentType),
1946
- instruction
2304
+ instruction,
2305
+ conditionalMembers: formStateRef.current ? getConditionalMembers(formStateRef.current) : []
1947
2306
  }), [pathKey, instruction, typePath, documentType, assistableDocId, requestRunInstruction]);
1948
2307
  const Region = useCallback(_props => {
1949
2308
  return /* @__PURE__ */jsx("div", {
@@ -2129,10 +2488,10 @@ const assistInspector = {
2129
2488
  showAsAction: false
2130
2489
  }),
2131
2490
  component: AssistInspectorWrapper,
2132
- onClose(_ref8) {
2491
+ onClose(_ref11) {
2133
2492
  let {
2134
2493
  params
2135
- } = _ref8;
2494
+ } = _ref11;
2136
2495
  return {
2137
2496
  params: typed({
2138
2497
  ...params,
@@ -2164,7 +2523,7 @@ function useAssistPresence(path, showFocusWithin) {
2164
2523
  if (!presence.path || !path.length) {
2165
2524
  return false;
2166
2525
  }
2167
- const statusPath = stringToPath(presence.path);
2526
+ const statusPath = stringToPath$2(presence.path);
2168
2527
  if (!showFocusWithin && statusPath.length !== path.length) {
2169
2528
  return false;
2170
2529
  }
@@ -2205,11 +2564,11 @@ var __template$3 = (cooked, raw) => __freeze$3(__defProp$3(cooked, "raw", {
2205
2564
  var _a$3, _b$1;
2206
2565
  const fadeIn = keyframes(_a$3 || (_a$3 = __template$3(["\n 0% {\n opacity: 0;\n transform: scale(0.75);\n }\n 40% {\n opacity: 0;\n transform: scale(0.75);\n }\n 100% {\n opacity: 1;\n transform: scale(1);\n }\n"])));
2207
2566
  const FadeInDiv = styled.div(_b$1 || (_b$1 = __template$3(["\n animation-name: ", ";\n animation-timing-function: ease-in-out;\n"])), fadeIn);
2208
- const FadeInContent = forwardRef(function FadeInContent2(_ref9, ref) {
2567
+ const FadeInContent = forwardRef(function FadeInContent2(_ref12, ref) {
2209
2568
  let {
2210
2569
  children,
2211
2570
  durationMs = 250
2212
- } = _ref9;
2571
+ } = _ref12;
2213
2572
  return /* @__PURE__ */jsx(FadeInDiv, {
2214
2573
  ref,
2215
2574
  style: {
@@ -2462,7 +2821,7 @@ function AssistFieldWrapper(props) {
2462
2821
  if (!isSupported || schemaType.name.startsWith("sanity.") || schemaType.name === contextDocumentTypeName) {
2463
2822
  return props.renderDefault(props);
2464
2823
  }
2465
- if (!isType(props.schemaType, "document") && props.inputId !== "root") {
2824
+ if (!isType(props.schemaType, "document") && props.inputId !== "root" && props.inputId !== assistFormId) {
2466
2825
  return /* @__PURE__ */jsx(AssistField, {
2467
2826
  ...props,
2468
2827
  children: props.children
@@ -2482,15 +2841,16 @@ function AssistField(props) {
2482
2841
  showOnboarding,
2483
2842
  dismissOnboarding
2484
2843
  } = useOnboardingFeature(fieldOnboardingKey);
2844
+ const singlePresence = presence[0];
2485
2845
  const actions = /* @__PURE__ */jsxs(Flex, {
2486
2846
  gap: 2,
2487
2847
  align: "center",
2488
2848
  justify: "space-between",
2489
- children: [presence.map(pre => /* @__PURE__ */jsx(Box, {
2849
+ children: [singlePresence && /* @__PURE__ */jsx(Box, {
2490
2850
  children: /* @__PURE__ */jsx(AiFieldPresence, {
2491
- presence: pre
2492
- }, pre.lastActiveAt)
2493
- }, pre.user.id)), isFirstAssisted && showOnboarding && /* @__PURE__ */jsx(AssistOnboardingPopover, {
2851
+ presence: singlePresence
2852
+ })
2853
+ }), isFirstAssisted && showOnboarding && /* @__PURE__ */jsx(AssistOnboardingPopover, {
2494
2854
  dismiss: dismissOnboarding
2495
2855
  })]
2496
2856
  });
@@ -2970,253 +3330,1500 @@ function AssistConnectorsOverlay(props) {
2970
3330
  }), DEBUG]
2971
3331
  });
2972
3332
  }
2973
- const legacyAssistDocumentIdPrefix = "sanity.ai.";
2974
- const legacyAssistDocumentTypeName = "sanity.ai.docType";
2975
- const legacyContextDocumentTypeName = "ai.instruction.context";
2976
- const legacyAssistStatusDocumentTypeName = "sanity.ai.instructionStatus";
2977
- const NO_ASSIST_DOCS = [];
2978
- const NO_CONTEXT_DOCS = [];
2979
- const NO_IDS = [];
2980
- function AlphaMigration() {
2981
- const [alphaAssistDocs, setAlphaAssistDocs] = useState(NO_ASSIST_DOCS);
2982
- const [contextDocs, setContextDocs] = useState(NO_CONTEXT_DOCS);
2983
- const [staleStatusDocIds, setStaleStatusDocs] = useState(NO_IDS);
2984
- const [error, setError] = useState(void 0);
2985
- const [progress, setProgress] = useState(void 0);
2986
- const toast = useToast();
2987
- const client = useClient({
2988
- apiVersion: "2023-06-01"
2989
- });
2990
- useEffect(() => {
2991
- let canUpdate = true;
2992
- client.fetch('\n {\n "assistDocs": *[_type=="'.concat(legacyAssistDocumentTypeName, '"],\n "staleStatusDocIds": *[_type=="').concat(legacyAssistStatusDocumentTypeName, '"]._id,\n "contextDocs": *[_type=="').concat(legacyContextDocumentTypeName, '"],\n }\n ')).then(result => {
2993
- var _a, _b, _c;
2994
- if (!canUpdate || !result) {
2995
- return;
2996
- }
2997
- setAlphaAssistDocs((_a = result == null ? void 0 : result.assistDocs) != null ? _a : NO_ASSIST_DOCS);
2998
- setStaleStatusDocs((_b = result == null ? void 0 : result.staleStatusDocIds) != null ? _b : NO_IDS);
2999
- setContextDocs((_c = result == null ? void 0 : result.contextDocs) != null ? _c : NO_CONTEXT_DOCS);
3000
- });
3001
- return () => {
3002
- canUpdate = false;
3003
- };
3004
- }, [client, setAlphaAssistDocs, setStaleStatusDocs, setContextDocs]);
3005
- const convert = useCallback(async () => {
3006
- try {
3007
- setProgress(1e-4);
3008
- const tasks = [() => convertContextDocs(client, contextDocs), subtaskProgress => deleteDocs(client, staleStatusDocIds, subtaskProgress), subtaskProgress => convertDocs(client, alphaAssistDocs, subtaskProgress), subtaskProgress => deleteDocs(client, contextDocs.map(d => d._id), subtaskProgress)];
3009
- const taskSize = 1 / tasks.length;
3010
- for (let i = 0; i < tasks.length; i++) {
3011
- const startProgress = i / tasks.length;
3012
- await tasks[i](subProgress => setProgress(startProgress + subProgress * taskSize));
3013
- setProgress((i + 1) / tasks.length);
3014
- }
3015
- setProgress(1);
3016
- setAlphaAssistDocs(NO_ASSIST_DOCS);
3017
- setContextDocs(NO_CONTEXT_DOCS);
3018
- setStaleStatusDocs(NO_IDS);
3019
- toast.push({
3020
- title: "Converted instructions to new format.",
3021
- status: "success",
3022
- closable: true
3023
- });
3024
- } catch (e) {
3025
- console.error(e);
3026
- toast.push({
3027
- title: "An error occurred",
3028
- status: "error",
3029
- closable: true
3030
- });
3031
- setError(e);
3032
- setProgress(void 0);
3333
+ var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
3334
+ function getDefaultExportFromCjs(x) {
3335
+ return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
3336
+ }
3337
+
3338
+ /**
3339
+ * Checks if `value` is classified as an `Array` object.
3340
+ *
3341
+ * @static
3342
+ * @memberOf _
3343
+ * @since 0.1.0
3344
+ * @category Lang
3345
+ * @param {*} value The value to check.
3346
+ * @returns {boolean} Returns `true` if `value` is an array, else `false`.
3347
+ * @example
3348
+ *
3349
+ * _.isArray([1, 2, 3]);
3350
+ * // => true
3351
+ *
3352
+ * _.isArray(document.body.children);
3353
+ * // => false
3354
+ *
3355
+ * _.isArray('abc');
3356
+ * // => false
3357
+ *
3358
+ * _.isArray(_.noop);
3359
+ * // => false
3360
+ */
3361
+
3362
+ var isArray$3 = Array.isArray;
3363
+ var isArray_1 = isArray$3;
3364
+
3365
+ /** Detect free variable `global` from Node.js. */
3366
+
3367
+ var freeGlobal$1 = typeof commonjsGlobal == 'object' && commonjsGlobal && commonjsGlobal.Object === Object && commonjsGlobal;
3368
+ var _freeGlobal = freeGlobal$1;
3369
+ var freeGlobal = _freeGlobal;
3370
+
3371
+ /** Detect free variable `self`. */
3372
+ var freeSelf = typeof self == 'object' && self && self.Object === Object && self;
3373
+
3374
+ /** Used as a reference to the global object. */
3375
+ var root$3 = freeGlobal || freeSelf || Function('return this')();
3376
+ var _root = root$3;
3377
+ var root$2 = _root;
3378
+
3379
+ /** Built-in value references. */
3380
+ var Symbol$3 = root$2.Symbol;
3381
+ var _Symbol = Symbol$3;
3382
+ var Symbol$2 = _Symbol;
3383
+
3384
+ /** Used for built-in method references. */
3385
+ var objectProto$4 = Object.prototype;
3386
+
3387
+ /** Used to check objects for own properties. */
3388
+ var hasOwnProperty$3 = objectProto$4.hasOwnProperty;
3389
+
3390
+ /**
3391
+ * Used to resolve the
3392
+ * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
3393
+ * of values.
3394
+ */
3395
+ var nativeObjectToString$1 = objectProto$4.toString;
3396
+
3397
+ /** Built-in value references. */
3398
+ var symToStringTag$1 = Symbol$2 ? Symbol$2.toStringTag : undefined;
3399
+
3400
+ /**
3401
+ * A specialized version of `baseGetTag` which ignores `Symbol.toStringTag` values.
3402
+ *
3403
+ * @private
3404
+ * @param {*} value The value to query.
3405
+ * @returns {string} Returns the raw `toStringTag`.
3406
+ */
3407
+ function getRawTag$1(value) {
3408
+ var isOwn = hasOwnProperty$3.call(value, symToStringTag$1),
3409
+ tag = value[symToStringTag$1];
3410
+ try {
3411
+ value[symToStringTag$1] = undefined;
3412
+ var unmasked = true;
3413
+ } catch (e) {}
3414
+ var result = nativeObjectToString$1.call(value);
3415
+ if (unmasked) {
3416
+ if (isOwn) {
3417
+ value[symToStringTag$1] = tag;
3418
+ } else {
3419
+ delete value[symToStringTag$1];
3033
3420
  }
3034
- }, [contextDocs, client, alphaAssistDocs, staleStatusDocIds, setProgress, toast]);
3035
- if ((alphaAssistDocs.length || staleStatusDocIds.length || contextDocs.length) && (!progress || progress < 1)) {
3036
- return /* @__PURE__ */jsx(Dialog, {
3037
- id: "outdated-assist-docs",
3038
- header: pluginTitle,
3039
- children: /* @__PURE__ */jsx(Card, {
3040
- padding: 3,
3041
- children: /* @__PURE__ */jsxs(Stack, {
3042
- space: 4,
3043
- style: {
3044
- maxWidth: 500
3045
- },
3046
- children: [/* @__PURE__ */jsxs(Text, {
3047
- size: 1,
3048
- children: ["It seems like this workspace contains documents from an", " ", /* @__PURE__ */jsxs("strong", {
3049
- children: ["older version of ", pluginTitle]
3050
- }), "."]
3051
- }), /* @__PURE__ */jsx(Text, {
3052
- size: 1,
3053
- children: "Cleanup is required."
3054
- }), error ? /* @__PURE__ */jsxs(Card, {
3055
- padding: 2,
3056
- tone: "critical",
3057
- border: true,
3058
- children: [/* @__PURE__ */jsx(Text, {
3059
- size: 1,
3060
- children: "An error occurred. See console for details."
3061
- }), " "]
3062
- }) : null, /* @__PURE__ */jsx(Button, {
3063
- icon: progress ? /* @__PURE__ */jsx(Box, {
3064
- style: {
3065
- marginTop: 5
3066
- },
3067
- children: /* @__PURE__ */jsx(Spinner, {})
3068
- }) : CheckmarkIcon,
3069
- disabled: !!progress,
3070
- text: progress ? "".concat(Math.floor(progress * 100), "%") : "Ok, convert to new format!",
3071
- tone: "primary",
3072
- onClick: convert
3073
- })]
3074
- })
3075
- })
3076
- });
3077
3421
  }
3078
- return null;
3422
+ return result;
3079
3423
  }
3080
- async function deleteDocs(client, ids, updateProgress) {
3081
- const chunkSize = 50;
3082
- for (let i = 0; i < ids.length; i += chunkSize) {
3083
- const progressCount = Math.min(ids.length, i + chunkSize);
3084
- const chunk = ids.slice(i, progressCount);
3085
- const trans = client.transaction();
3086
- chunk.forEach(id => trans.delete(id));
3087
- await trans.commit();
3088
- updateProgress(progressCount / ids.length);
3424
+ var _getRawTag = getRawTag$1;
3425
+
3426
+ /** Used for built-in method references. */
3427
+
3428
+ var objectProto$3 = Object.prototype;
3429
+
3430
+ /**
3431
+ * Used to resolve the
3432
+ * [`toStringTag`](http://ecma-international.org/ecma-262/7.0/#sec-object.prototype.tostring)
3433
+ * of values.
3434
+ */
3435
+ var nativeObjectToString = objectProto$3.toString;
3436
+
3437
+ /**
3438
+ * Converts `value` to a string using `Object.prototype.toString`.
3439
+ *
3440
+ * @private
3441
+ * @param {*} value The value to convert.
3442
+ * @returns {string} Returns the converted string.
3443
+ */
3444
+ function objectToString$1(value) {
3445
+ return nativeObjectToString.call(value);
3446
+ }
3447
+ var _objectToString = objectToString$1;
3448
+ var Symbol$1 = _Symbol,
3449
+ getRawTag = _getRawTag,
3450
+ objectToString = _objectToString;
3451
+
3452
+ /** `Object#toString` result references. */
3453
+ var nullTag = '[object Null]',
3454
+ undefinedTag = '[object Undefined]';
3455
+
3456
+ /** Built-in value references. */
3457
+ var symToStringTag = Symbol$1 ? Symbol$1.toStringTag : undefined;
3458
+
3459
+ /**
3460
+ * The base implementation of `getTag` without fallbacks for buggy environments.
3461
+ *
3462
+ * @private
3463
+ * @param {*} value The value to query.
3464
+ * @returns {string} Returns the `toStringTag`.
3465
+ */
3466
+ function baseGetTag$2(value) {
3467
+ if (value == null) {
3468
+ return value === undefined ? undefinedTag : nullTag;
3089
3469
  }
3470
+ return symToStringTag && symToStringTag in Object(value) ? getRawTag(value) : objectToString(value);
3090
3471
  }
3091
- async function convertContextDocs(client, docs) {
3092
- const trans = client.transaction();
3093
- for (const doc of docs) {
3094
- const {
3095
- _id,
3096
- _type,
3097
- ...rest
3098
- } = doc;
3099
- trans.createOrReplace({
3100
- ...rest,
3101
- _id: "port.".concat(_id),
3102
- _alphaId: _id,
3103
- _type: contextDocumentTypeName
3104
- });
3105
- }
3106
- await trans.commit();
3107
- }
3108
- async function convertDocs(client, docs, updateProgress) {
3109
- const chunkSize = 10;
3110
- for (let i = 0; i < docs.length; i += chunkSize) {
3111
- const progressCount = Math.min(docs.length, i + chunkSize);
3112
- const chunk = docs.slice(i, progressCount);
3113
- const trans = client.transaction();
3114
- const contextDocs = await client.fetch('*[_type=="'.concat(contextDocumentTypeName, '" && _alphaId != null]{_id, _alphaId}'));
3115
- chunk.forEach(oldDoc => {
3116
- var _a;
3117
- const documentType = oldDoc._id.replace(new RegExp("^(".concat(legacyAssistDocumentIdPrefix, "|").concat(assistDocumentIdPrefix, ")")), "");
3118
- const id = assistDocumentId(documentType);
3119
- const fields = ((_a = oldDoc.fields) != null ? _a : []).filter(field => {
3120
- var _a2;
3121
- return (_a2 = field.instructions) == null ? void 0 : _a2.length;
3122
- }).map(oldField => {
3123
- var _a2;
3124
- const instructions = ((_a2 = oldField.instructions) != null ? _a2 : []).map(inst => {
3125
- var _a3;
3126
- const prompt = ((_a3 = inst.prompt) != null ? _a3 : []).map(block => {
3127
- return mapBlock(block, contextDocs);
3128
- });
3129
- return {
3130
- ...inst,
3131
- _type: instructionTypeName,
3132
- prompt
3133
- };
3134
- });
3135
- return {
3136
- ...oldField,
3137
- _type: assistFieldTypeName,
3138
- instructions
3139
- };
3140
- });
3141
- if (fields.length) {
3142
- trans.createOrReplace({
3143
- _id: id,
3144
- _type: assistDocumentTypeName,
3145
- fields
3146
- });
3147
- }
3148
- trans.delete(oldDoc._id);
3149
- });
3150
- await trans.commit();
3151
- updateProgress(progressCount / docs.length);
3152
- }
3472
+ var _baseGetTag = baseGetTag$2;
3473
+
3474
+ /**
3475
+ * Checks if `value` is object-like. A value is object-like if it's not `null`
3476
+ * and has a `typeof` result of "object".
3477
+ *
3478
+ * @static
3479
+ * @memberOf _
3480
+ * @since 4.0.0
3481
+ * @category Lang
3482
+ * @param {*} value The value to check.
3483
+ * @returns {boolean} Returns `true` if `value` is object-like, else `false`.
3484
+ * @example
3485
+ *
3486
+ * _.isObjectLike({});
3487
+ * // => true
3488
+ *
3489
+ * _.isObjectLike([1, 2, 3]);
3490
+ * // => true
3491
+ *
3492
+ * _.isObjectLike(_.noop);
3493
+ * // => false
3494
+ *
3495
+ * _.isObjectLike(null);
3496
+ * // => false
3497
+ */
3498
+
3499
+ function isObjectLike$1(value) {
3500
+ return value != null && typeof value == 'object';
3153
3501
  }
3154
- function isFieldRef(block) {
3155
- return block._type === "sanity.ai.prompt.fieldRef";
3502
+ var isObjectLike_1 = isObjectLike$1;
3503
+ var baseGetTag$1 = _baseGetTag,
3504
+ isObjectLike = isObjectLike_1;
3505
+
3506
+ /** `Object#toString` result references. */
3507
+ var symbolTag = '[object Symbol]';
3508
+
3509
+ /**
3510
+ * Checks if `value` is classified as a `Symbol` primitive or object.
3511
+ *
3512
+ * @static
3513
+ * @memberOf _
3514
+ * @since 4.0.0
3515
+ * @category Lang
3516
+ * @param {*} value The value to check.
3517
+ * @returns {boolean} Returns `true` if `value` is a symbol, else `false`.
3518
+ * @example
3519
+ *
3520
+ * _.isSymbol(Symbol.iterator);
3521
+ * // => true
3522
+ *
3523
+ * _.isSymbol('abc');
3524
+ * // => false
3525
+ */
3526
+ function isSymbol$3(value) {
3527
+ return typeof value == 'symbol' || isObjectLike(value) && baseGetTag$1(value) == symbolTag;
3528
+ }
3529
+ var isSymbol_1 = isSymbol$3;
3530
+ var isArray$2 = isArray_1,
3531
+ isSymbol$2 = isSymbol_1;
3532
+
3533
+ /** Used to match property names within property paths. */
3534
+ var reIsDeepProp = /\.|\[(?:[^[\]]*|(["'])(?:(?!\1)[^\\]|\\.)*?\1)\]/,
3535
+ reIsPlainProp = /^\w*$/;
3536
+
3537
+ /**
3538
+ * Checks if `value` is a property name and not a property path.
3539
+ *
3540
+ * @private
3541
+ * @param {*} value The value to check.
3542
+ * @param {Object} [object] The object to query keys on.
3543
+ * @returns {boolean} Returns `true` if `value` is a property name, else `false`.
3544
+ */
3545
+ function isKey$1(value, object) {
3546
+ if (isArray$2(value)) {
3547
+ return false;
3548
+ }
3549
+ var type = typeof value;
3550
+ if (type == 'number' || type == 'symbol' || type == 'boolean' || value == null || isSymbol$2(value)) {
3551
+ return true;
3552
+ }
3553
+ return reIsPlainProp.test(value) || !reIsDeepProp.test(value) || object != null && value in Object(object);
3156
3554
  }
3157
- function isContext(block) {
3158
- return block._type === "sanity.ai.prompt.context";
3555
+ var _isKey = isKey$1;
3556
+
3557
+ /**
3558
+ * Checks if `value` is the
3559
+ * [language type](http://www.ecma-international.org/ecma-262/7.0/#sec-ecmascript-language-types)
3560
+ * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)
3561
+ *
3562
+ * @static
3563
+ * @memberOf _
3564
+ * @since 0.1.0
3565
+ * @category Lang
3566
+ * @param {*} value The value to check.
3567
+ * @returns {boolean} Returns `true` if `value` is an object, else `false`.
3568
+ * @example
3569
+ *
3570
+ * _.isObject({});
3571
+ * // => true
3572
+ *
3573
+ * _.isObject([1, 2, 3]);
3574
+ * // => true
3575
+ *
3576
+ * _.isObject(_.noop);
3577
+ * // => true
3578
+ *
3579
+ * _.isObject(null);
3580
+ * // => false
3581
+ */
3582
+
3583
+ function isObject$2(value) {
3584
+ var type = typeof value;
3585
+ return value != null && (type == 'object' || type == 'function');
3159
3586
  }
3160
- function isUserInput(block) {
3161
- return block._type === "sanity.ai.prompt.userInput";
3587
+ var isObject_1 = isObject$2;
3588
+ var baseGetTag = _baseGetTag,
3589
+ isObject$1 = isObject_1;
3590
+
3591
+ /** `Object#toString` result references. */
3592
+ var asyncTag = '[object AsyncFunction]',
3593
+ funcTag = '[object Function]',
3594
+ genTag = '[object GeneratorFunction]',
3595
+ proxyTag = '[object Proxy]';
3596
+
3597
+ /**
3598
+ * Checks if `value` is classified as a `Function` object.
3599
+ *
3600
+ * @static
3601
+ * @memberOf _
3602
+ * @since 0.1.0
3603
+ * @category Lang
3604
+ * @param {*} value The value to check.
3605
+ * @returns {boolean} Returns `true` if `value` is a function, else `false`.
3606
+ * @example
3607
+ *
3608
+ * _.isFunction(_);
3609
+ * // => true
3610
+ *
3611
+ * _.isFunction(/abc/);
3612
+ * // => false
3613
+ */
3614
+ function isFunction$1(value) {
3615
+ if (!isObject$1(value)) {
3616
+ return false;
3617
+ }
3618
+ // The use of `Object#toString` avoids issues with the `typeof` operator
3619
+ // in Safari 9 which returns 'object' for typed arrays and other constructors.
3620
+ var tag = baseGetTag(value);
3621
+ return tag == funcTag || tag == genTag || tag == asyncTag || tag == proxyTag;
3162
3622
  }
3163
- function isSpan(block) {
3164
- return block._type === "span";
3623
+ var isFunction_1 = isFunction$1;
3624
+ var root$1 = _root;
3625
+
3626
+ /** Used to detect overreaching core-js shims. */
3627
+ var coreJsData$1 = root$1['__core-js_shared__'];
3628
+ var _coreJsData = coreJsData$1;
3629
+ var coreJsData = _coreJsData;
3630
+
3631
+ /** Used to detect methods masquerading as native. */
3632
+ var maskSrcKey = function () {
3633
+ var uid = /[^.]+$/.exec(coreJsData && coreJsData.keys && coreJsData.keys.IE_PROTO || '');
3634
+ return uid ? 'Symbol(src)_1.' + uid : '';
3635
+ }();
3636
+
3637
+ /**
3638
+ * Checks if `func` has its source masked.
3639
+ *
3640
+ * @private
3641
+ * @param {Function} func The function to check.
3642
+ * @returns {boolean} Returns `true` if `func` is masked, else `false`.
3643
+ */
3644
+ function isMasked$1(func) {
3645
+ return !!maskSrcKey && maskSrcKey in func;
3646
+ }
3647
+ var _isMasked = isMasked$1;
3648
+
3649
+ /** Used for built-in method references. */
3650
+
3651
+ var funcProto$1 = Function.prototype;
3652
+
3653
+ /** Used to resolve the decompiled source of functions. */
3654
+ var funcToString$1 = funcProto$1.toString;
3655
+
3656
+ /**
3657
+ * Converts `func` to its source code.
3658
+ *
3659
+ * @private
3660
+ * @param {Function} func The function to convert.
3661
+ * @returns {string} Returns the source code.
3662
+ */
3663
+ function toSource$1(func) {
3664
+ if (func != null) {
3665
+ try {
3666
+ return funcToString$1.call(func);
3667
+ } catch (e) {}
3668
+ try {
3669
+ return func + '';
3670
+ } catch (e) {}
3671
+ }
3672
+ return '';
3165
3673
  }
3166
- function mapBlock(block, migratedContexts) {
3167
- var _a, _b, _c, _d;
3168
- if (isFieldRef(block)) {
3169
- return {
3170
- ...block,
3171
- _type: fieldReferenceTypeName
3172
- };
3674
+ var _toSource = toSource$1;
3675
+ var isFunction = isFunction_1,
3676
+ isMasked = _isMasked,
3677
+ isObject = isObject_1,
3678
+ toSource = _toSource;
3679
+
3680
+ /**
3681
+ * Used to match `RegExp`
3682
+ * [syntax characters](http://ecma-international.org/ecma-262/7.0/#sec-patterns).
3683
+ */
3684
+ var reRegExpChar = /[\\^$.*+?()[\]{}|]/g;
3685
+
3686
+ /** Used to detect host constructors (Safari). */
3687
+ var reIsHostCtor = /^\[object .+?Constructor\]$/;
3688
+
3689
+ /** Used for built-in method references. */
3690
+ var funcProto = Function.prototype,
3691
+ objectProto$2 = Object.prototype;
3692
+
3693
+ /** Used to resolve the decompiled source of functions. */
3694
+ var funcToString = funcProto.toString;
3695
+
3696
+ /** Used to check objects for own properties. */
3697
+ var hasOwnProperty$2 = objectProto$2.hasOwnProperty;
3698
+
3699
+ /** Used to detect if a method is native. */
3700
+ var reIsNative = RegExp('^' + funcToString.call(hasOwnProperty$2).replace(reRegExpChar, '\\$&').replace(/hasOwnProperty|(function).*?(?=\\\()| for .+?(?=\\\])/g, '$1.*?') + '$');
3701
+
3702
+ /**
3703
+ * The base implementation of `_.isNative` without bad shim checks.
3704
+ *
3705
+ * @private
3706
+ * @param {*} value The value to check.
3707
+ * @returns {boolean} Returns `true` if `value` is a native function,
3708
+ * else `false`.
3709
+ */
3710
+ function baseIsNative$1(value) {
3711
+ if (!isObject(value) || isMasked(value)) {
3712
+ return false;
3173
3713
  }
3174
- if (isUserInput(block)) {
3175
- return {
3176
- ...block,
3177
- _type: userInputTypeName
3178
- };
3714
+ var pattern = isFunction(value) ? reIsNative : reIsHostCtor;
3715
+ return pattern.test(toSource(value));
3716
+ }
3717
+ var _baseIsNative = baseIsNative$1;
3718
+
3719
+ /**
3720
+ * Gets the value at `key` of `object`.
3721
+ *
3722
+ * @private
3723
+ * @param {Object} [object] The object to query.
3724
+ * @param {string} key The key of the property to get.
3725
+ * @returns {*} Returns the property value.
3726
+ */
3727
+
3728
+ function getValue$1(object, key) {
3729
+ return object == null ? undefined : object[key];
3730
+ }
3731
+ var _getValue = getValue$1;
3732
+ var baseIsNative = _baseIsNative,
3733
+ getValue = _getValue;
3734
+
3735
+ /**
3736
+ * Gets the native function at `key` of `object`.
3737
+ *
3738
+ * @private
3739
+ * @param {Object} object The object to query.
3740
+ * @param {string} key The key of the method to get.
3741
+ * @returns {*} Returns the function if it's native, else `undefined`.
3742
+ */
3743
+ function getNative$2(object, key) {
3744
+ var value = getValue(object, key);
3745
+ return baseIsNative(value) ? value : undefined;
3746
+ }
3747
+ var _getNative = getNative$2;
3748
+ var getNative$1 = _getNative;
3749
+
3750
+ /* Built-in method references that are verified to be native. */
3751
+ var nativeCreate$4 = getNative$1(Object, 'create');
3752
+ var _nativeCreate = nativeCreate$4;
3753
+ var nativeCreate$3 = _nativeCreate;
3754
+
3755
+ /**
3756
+ * Removes all key-value entries from the hash.
3757
+ *
3758
+ * @private
3759
+ * @name clear
3760
+ * @memberOf Hash
3761
+ */
3762
+ function hashClear$1() {
3763
+ this.__data__ = nativeCreate$3 ? nativeCreate$3(null) : {};
3764
+ this.size = 0;
3765
+ }
3766
+ var _hashClear = hashClear$1;
3767
+
3768
+ /**
3769
+ * Removes `key` and its value from the hash.
3770
+ *
3771
+ * @private
3772
+ * @name delete
3773
+ * @memberOf Hash
3774
+ * @param {Object} hash The hash to modify.
3775
+ * @param {string} key The key of the value to remove.
3776
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
3777
+ */
3778
+
3779
+ function hashDelete$1(key) {
3780
+ var result = this.has(key) && delete this.__data__[key];
3781
+ this.size -= result ? 1 : 0;
3782
+ return result;
3783
+ }
3784
+ var _hashDelete = hashDelete$1;
3785
+ var nativeCreate$2 = _nativeCreate;
3786
+
3787
+ /** Used to stand-in for `undefined` hash values. */
3788
+ var HASH_UNDEFINED$1 = '__lodash_hash_undefined__';
3789
+
3790
+ /** Used for built-in method references. */
3791
+ var objectProto$1 = Object.prototype;
3792
+
3793
+ /** Used to check objects for own properties. */
3794
+ var hasOwnProperty$1 = objectProto$1.hasOwnProperty;
3795
+
3796
+ /**
3797
+ * Gets the hash value for `key`.
3798
+ *
3799
+ * @private
3800
+ * @name get
3801
+ * @memberOf Hash
3802
+ * @param {string} key The key of the value to get.
3803
+ * @returns {*} Returns the entry value.
3804
+ */
3805
+ function hashGet$1(key) {
3806
+ var data = this.__data__;
3807
+ if (nativeCreate$2) {
3808
+ var result = data[key];
3809
+ return result === HASH_UNDEFINED$1 ? undefined : result;
3179
3810
  }
3180
- if (isContext(block)) {
3181
- const newBlock = {
3182
- ...block,
3183
- _type: instructionContextTypeName,
3184
- reference: {
3185
- _type: "reference",
3186
- _ref: (_c = (_a = migratedContexts.find(c => {
3187
- var _a2;
3188
- return c._alphaId === ((_a2 = block.reference) == null ? void 0 : _a2._ref);
3189
- })) == null ? void 0 : _a._id) != null ? _c : (_b = block.reference) == null ? void 0 : _b._ref
3190
- }
3191
- };
3192
- return newBlock;
3811
+ return hasOwnProperty$1.call(data, key) ? data[key] : undefined;
3812
+ }
3813
+ var _hashGet = hashGet$1;
3814
+ var nativeCreate$1 = _nativeCreate;
3815
+
3816
+ /** Used for built-in method references. */
3817
+ var objectProto = Object.prototype;
3818
+
3819
+ /** Used to check objects for own properties. */
3820
+ var hasOwnProperty = objectProto.hasOwnProperty;
3821
+
3822
+ /**
3823
+ * Checks if a hash value for `key` exists.
3824
+ *
3825
+ * @private
3826
+ * @name has
3827
+ * @memberOf Hash
3828
+ * @param {string} key The key of the entry to check.
3829
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
3830
+ */
3831
+ function hashHas$1(key) {
3832
+ var data = this.__data__;
3833
+ return nativeCreate$1 ? data[key] !== undefined : hasOwnProperty.call(data, key);
3834
+ }
3835
+ var _hashHas = hashHas$1;
3836
+ var nativeCreate = _nativeCreate;
3837
+
3838
+ /** Used to stand-in for `undefined` hash values. */
3839
+ var HASH_UNDEFINED = '__lodash_hash_undefined__';
3840
+
3841
+ /**
3842
+ * Sets the hash `key` to `value`.
3843
+ *
3844
+ * @private
3845
+ * @name set
3846
+ * @memberOf Hash
3847
+ * @param {string} key The key of the value to set.
3848
+ * @param {*} value The value to set.
3849
+ * @returns {Object} Returns the hash instance.
3850
+ */
3851
+ function hashSet$1(key, value) {
3852
+ var data = this.__data__;
3853
+ this.size += this.has(key) ? 0 : 1;
3854
+ data[key] = nativeCreate && value === undefined ? HASH_UNDEFINED : value;
3855
+ return this;
3856
+ }
3857
+ var _hashSet = hashSet$1;
3858
+ var hashClear = _hashClear,
3859
+ hashDelete = _hashDelete,
3860
+ hashGet = _hashGet,
3861
+ hashHas = _hashHas,
3862
+ hashSet = _hashSet;
3863
+
3864
+ /**
3865
+ * Creates a hash object.
3866
+ *
3867
+ * @private
3868
+ * @constructor
3869
+ * @param {Array} [entries] The key-value pairs to cache.
3870
+ */
3871
+ function Hash$1(entries) {
3872
+ var index = -1,
3873
+ length = entries == null ? 0 : entries.length;
3874
+ this.clear();
3875
+ while (++index < length) {
3876
+ var entry = entries[index];
3877
+ this.set(entry[0], entry[1]);
3193
3878
  }
3194
- if (isSpan(block)) {
3195
- return block;
3879
+ }
3880
+
3881
+ // Add methods to `Hash`.
3882
+ Hash$1.prototype.clear = hashClear;
3883
+ Hash$1.prototype['delete'] = hashDelete;
3884
+ Hash$1.prototype.get = hashGet;
3885
+ Hash$1.prototype.has = hashHas;
3886
+ Hash$1.prototype.set = hashSet;
3887
+ var _Hash = Hash$1;
3888
+
3889
+ /**
3890
+ * Removes all key-value entries from the list cache.
3891
+ *
3892
+ * @private
3893
+ * @name clear
3894
+ * @memberOf ListCache
3895
+ */
3896
+
3897
+ function listCacheClear$1() {
3898
+ this.__data__ = [];
3899
+ this.size = 0;
3900
+ }
3901
+ var _listCacheClear = listCacheClear$1;
3902
+
3903
+ /**
3904
+ * Performs a
3905
+ * [`SameValueZero`](http://ecma-international.org/ecma-262/7.0/#sec-samevaluezero)
3906
+ * comparison between two values to determine if they are equivalent.
3907
+ *
3908
+ * @static
3909
+ * @memberOf _
3910
+ * @since 4.0.0
3911
+ * @category Lang
3912
+ * @param {*} value The value to compare.
3913
+ * @param {*} other The other value to compare.
3914
+ * @returns {boolean} Returns `true` if the values are equivalent, else `false`.
3915
+ * @example
3916
+ *
3917
+ * var object = { 'a': 1 };
3918
+ * var other = { 'a': 1 };
3919
+ *
3920
+ * _.eq(object, object);
3921
+ * // => true
3922
+ *
3923
+ * _.eq(object, other);
3924
+ * // => false
3925
+ *
3926
+ * _.eq('a', 'a');
3927
+ * // => true
3928
+ *
3929
+ * _.eq('a', Object('a'));
3930
+ * // => false
3931
+ *
3932
+ * _.eq(NaN, NaN);
3933
+ * // => true
3934
+ */
3935
+
3936
+ function eq$1(value, other) {
3937
+ return value === other || value !== value && other !== other;
3938
+ }
3939
+ var eq_1 = eq$1;
3940
+ var eq = eq_1;
3941
+
3942
+ /**
3943
+ * Gets the index at which the `key` is found in `array` of key-value pairs.
3944
+ *
3945
+ * @private
3946
+ * @param {Array} array The array to inspect.
3947
+ * @param {*} key The key to search for.
3948
+ * @returns {number} Returns the index of the matched value, else `-1`.
3949
+ */
3950
+ function assocIndexOf$4(array, key) {
3951
+ var length = array.length;
3952
+ while (length--) {
3953
+ if (eq(array[length][0], key)) {
3954
+ return length;
3955
+ }
3196
3956
  }
3197
- const textBlock = block;
3198
- return {
3199
- ...textBlock,
3200
- children: ((_d = textBlock.children) != null ? _d : []).map(child => mapBlock(child, migratedContexts))
3957
+ return -1;
3958
+ }
3959
+ var _assocIndexOf = assocIndexOf$4;
3960
+ var assocIndexOf$3 = _assocIndexOf;
3961
+
3962
+ /** Used for built-in method references. */
3963
+ var arrayProto = Array.prototype;
3964
+
3965
+ /** Built-in value references. */
3966
+ var splice = arrayProto.splice;
3967
+
3968
+ /**
3969
+ * Removes `key` and its value from the list cache.
3970
+ *
3971
+ * @private
3972
+ * @name delete
3973
+ * @memberOf ListCache
3974
+ * @param {string} key The key of the value to remove.
3975
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
3976
+ */
3977
+ function listCacheDelete$1(key) {
3978
+ var data = this.__data__,
3979
+ index = assocIndexOf$3(data, key);
3980
+ if (index < 0) {
3981
+ return false;
3982
+ }
3983
+ var lastIndex = data.length - 1;
3984
+ if (index == lastIndex) {
3985
+ data.pop();
3986
+ } else {
3987
+ splice.call(data, index, 1);
3988
+ }
3989
+ --this.size;
3990
+ return true;
3991
+ }
3992
+ var _listCacheDelete = listCacheDelete$1;
3993
+ var assocIndexOf$2 = _assocIndexOf;
3994
+
3995
+ /**
3996
+ * Gets the list cache value for `key`.
3997
+ *
3998
+ * @private
3999
+ * @name get
4000
+ * @memberOf ListCache
4001
+ * @param {string} key The key of the value to get.
4002
+ * @returns {*} Returns the entry value.
4003
+ */
4004
+ function listCacheGet$1(key) {
4005
+ var data = this.__data__,
4006
+ index = assocIndexOf$2(data, key);
4007
+ return index < 0 ? undefined : data[index][1];
4008
+ }
4009
+ var _listCacheGet = listCacheGet$1;
4010
+ var assocIndexOf$1 = _assocIndexOf;
4011
+
4012
+ /**
4013
+ * Checks if a list cache value for `key` exists.
4014
+ *
4015
+ * @private
4016
+ * @name has
4017
+ * @memberOf ListCache
4018
+ * @param {string} key The key of the entry to check.
4019
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
4020
+ */
4021
+ function listCacheHas$1(key) {
4022
+ return assocIndexOf$1(this.__data__, key) > -1;
4023
+ }
4024
+ var _listCacheHas = listCacheHas$1;
4025
+ var assocIndexOf = _assocIndexOf;
4026
+
4027
+ /**
4028
+ * Sets the list cache `key` to `value`.
4029
+ *
4030
+ * @private
4031
+ * @name set
4032
+ * @memberOf ListCache
4033
+ * @param {string} key The key of the value to set.
4034
+ * @param {*} value The value to set.
4035
+ * @returns {Object} Returns the list cache instance.
4036
+ */
4037
+ function listCacheSet$1(key, value) {
4038
+ var data = this.__data__,
4039
+ index = assocIndexOf(data, key);
4040
+ if (index < 0) {
4041
+ ++this.size;
4042
+ data.push([key, value]);
4043
+ } else {
4044
+ data[index][1] = value;
4045
+ }
4046
+ return this;
4047
+ }
4048
+ var _listCacheSet = listCacheSet$1;
4049
+ var listCacheClear = _listCacheClear,
4050
+ listCacheDelete = _listCacheDelete,
4051
+ listCacheGet = _listCacheGet,
4052
+ listCacheHas = _listCacheHas,
4053
+ listCacheSet = _listCacheSet;
4054
+
4055
+ /**
4056
+ * Creates an list cache object.
4057
+ *
4058
+ * @private
4059
+ * @constructor
4060
+ * @param {Array} [entries] The key-value pairs to cache.
4061
+ */
4062
+ function ListCache$1(entries) {
4063
+ var index = -1,
4064
+ length = entries == null ? 0 : entries.length;
4065
+ this.clear();
4066
+ while (++index < length) {
4067
+ var entry = entries[index];
4068
+ this.set(entry[0], entry[1]);
4069
+ }
4070
+ }
4071
+
4072
+ // Add methods to `ListCache`.
4073
+ ListCache$1.prototype.clear = listCacheClear;
4074
+ ListCache$1.prototype['delete'] = listCacheDelete;
4075
+ ListCache$1.prototype.get = listCacheGet;
4076
+ ListCache$1.prototype.has = listCacheHas;
4077
+ ListCache$1.prototype.set = listCacheSet;
4078
+ var _ListCache = ListCache$1;
4079
+ var getNative = _getNative,
4080
+ root = _root;
4081
+
4082
+ /* Built-in method references that are verified to be native. */
4083
+ var Map$2 = getNative(root, 'Map');
4084
+ var _Map = Map$2;
4085
+ var Hash = _Hash,
4086
+ ListCache = _ListCache,
4087
+ Map$1 = _Map;
4088
+
4089
+ /**
4090
+ * Removes all key-value entries from the map.
4091
+ *
4092
+ * @private
4093
+ * @name clear
4094
+ * @memberOf MapCache
4095
+ */
4096
+ function mapCacheClear$1() {
4097
+ this.size = 0;
4098
+ this.__data__ = {
4099
+ 'hash': new Hash(),
4100
+ 'map': new (Map$1 || ListCache)(),
4101
+ 'string': new Hash()
3201
4102
  };
3202
4103
  }
3203
- function AssistLayout(props) {
3204
- var _a;
3205
- const [connectors, setConnectors] = useState([]);
3206
- const migrate = (_a = props.config.alphaMigration) != null ? _a : true;
3207
- return /* @__PURE__ */jsxs(AiAssistanceConfigProvider, {
3208
- config: props.config,
3209
- children: [migrate ? /* @__PURE__ */jsx(AlphaMigration, {}) : null, /* @__PURE__ */jsx(RunInstructionProvider, {
3210
- children: /* @__PURE__ */jsxs(ConnectorsProvider, {
3211
- onConnectorsChange: setConnectors,
3212
- children: [props.renderDefault(props), /* @__PURE__ */jsx(ThemeProvider, {
3213
- tone: "default",
3214
- children: /* @__PURE__ */jsx(AssistConnectorsOverlay, {
3215
- connectors
4104
+ var _mapCacheClear = mapCacheClear$1;
4105
+
4106
+ /**
4107
+ * Checks if `value` is suitable for use as unique object key.
4108
+ *
4109
+ * @private
4110
+ * @param {*} value The value to check.
4111
+ * @returns {boolean} Returns `true` if `value` is suitable, else `false`.
4112
+ */
4113
+
4114
+ function isKeyable$1(value) {
4115
+ var type = typeof value;
4116
+ return type == 'string' || type == 'number' || type == 'symbol' || type == 'boolean' ? value !== '__proto__' : value === null;
4117
+ }
4118
+ var _isKeyable = isKeyable$1;
4119
+ var isKeyable = _isKeyable;
4120
+
4121
+ /**
4122
+ * Gets the data for `map`.
4123
+ *
4124
+ * @private
4125
+ * @param {Object} map The map to query.
4126
+ * @param {string} key The reference key.
4127
+ * @returns {*} Returns the map data.
4128
+ */
4129
+ function getMapData$4(map, key) {
4130
+ var data = map.__data__;
4131
+ return isKeyable(key) ? data[typeof key == 'string' ? 'string' : 'hash'] : data.map;
4132
+ }
4133
+ var _getMapData = getMapData$4;
4134
+ var getMapData$3 = _getMapData;
4135
+
4136
+ /**
4137
+ * Removes `key` and its value from the map.
4138
+ *
4139
+ * @private
4140
+ * @name delete
4141
+ * @memberOf MapCache
4142
+ * @param {string} key The key of the value to remove.
4143
+ * @returns {boolean} Returns `true` if the entry was removed, else `false`.
4144
+ */
4145
+ function mapCacheDelete$1(key) {
4146
+ var result = getMapData$3(this, key)['delete'](key);
4147
+ this.size -= result ? 1 : 0;
4148
+ return result;
4149
+ }
4150
+ var _mapCacheDelete = mapCacheDelete$1;
4151
+ var getMapData$2 = _getMapData;
4152
+
4153
+ /**
4154
+ * Gets the map value for `key`.
4155
+ *
4156
+ * @private
4157
+ * @name get
4158
+ * @memberOf MapCache
4159
+ * @param {string} key The key of the value to get.
4160
+ * @returns {*} Returns the entry value.
4161
+ */
4162
+ function mapCacheGet$1(key) {
4163
+ return getMapData$2(this, key).get(key);
4164
+ }
4165
+ var _mapCacheGet = mapCacheGet$1;
4166
+ var getMapData$1 = _getMapData;
4167
+
4168
+ /**
4169
+ * Checks if a map value for `key` exists.
4170
+ *
4171
+ * @private
4172
+ * @name has
4173
+ * @memberOf MapCache
4174
+ * @param {string} key The key of the entry to check.
4175
+ * @returns {boolean} Returns `true` if an entry for `key` exists, else `false`.
4176
+ */
4177
+ function mapCacheHas$1(key) {
4178
+ return getMapData$1(this, key).has(key);
4179
+ }
4180
+ var _mapCacheHas = mapCacheHas$1;
4181
+ var getMapData = _getMapData;
4182
+
4183
+ /**
4184
+ * Sets the map `key` to `value`.
4185
+ *
4186
+ * @private
4187
+ * @name set
4188
+ * @memberOf MapCache
4189
+ * @param {string} key The key of the value to set.
4190
+ * @param {*} value The value to set.
4191
+ * @returns {Object} Returns the map cache instance.
4192
+ */
4193
+ function mapCacheSet$1(key, value) {
4194
+ var data = getMapData(this, key),
4195
+ size = data.size;
4196
+ data.set(key, value);
4197
+ this.size += data.size == size ? 0 : 1;
4198
+ return this;
4199
+ }
4200
+ var _mapCacheSet = mapCacheSet$1;
4201
+ var mapCacheClear = _mapCacheClear,
4202
+ mapCacheDelete = _mapCacheDelete,
4203
+ mapCacheGet = _mapCacheGet,
4204
+ mapCacheHas = _mapCacheHas,
4205
+ mapCacheSet = _mapCacheSet;
4206
+
4207
+ /**
4208
+ * Creates a map cache object to store key-value pairs.
4209
+ *
4210
+ * @private
4211
+ * @constructor
4212
+ * @param {Array} [entries] The key-value pairs to cache.
4213
+ */
4214
+ function MapCache$1(entries) {
4215
+ var index = -1,
4216
+ length = entries == null ? 0 : entries.length;
4217
+ this.clear();
4218
+ while (++index < length) {
4219
+ var entry = entries[index];
4220
+ this.set(entry[0], entry[1]);
4221
+ }
4222
+ }
4223
+
4224
+ // Add methods to `MapCache`.
4225
+ MapCache$1.prototype.clear = mapCacheClear;
4226
+ MapCache$1.prototype['delete'] = mapCacheDelete;
4227
+ MapCache$1.prototype.get = mapCacheGet;
4228
+ MapCache$1.prototype.has = mapCacheHas;
4229
+ MapCache$1.prototype.set = mapCacheSet;
4230
+ var _MapCache = MapCache$1;
4231
+ var MapCache = _MapCache;
4232
+
4233
+ /** Error message constants. */
4234
+ var FUNC_ERROR_TEXT = 'Expected a function';
4235
+
4236
+ /**
4237
+ * Creates a function that memoizes the result of `func`. If `resolver` is
4238
+ * provided, it determines the cache key for storing the result based on the
4239
+ * arguments provided to the memoized function. By default, the first argument
4240
+ * provided to the memoized function is used as the map cache key. The `func`
4241
+ * is invoked with the `this` binding of the memoized function.
4242
+ *
4243
+ * **Note:** The cache is exposed as the `cache` property on the memoized
4244
+ * function. Its creation may be customized by replacing the `_.memoize.Cache`
4245
+ * constructor with one whose instances implement the
4246
+ * [`Map`](http://ecma-international.org/ecma-262/7.0/#sec-properties-of-the-map-prototype-object)
4247
+ * method interface of `clear`, `delete`, `get`, `has`, and `set`.
4248
+ *
4249
+ * @static
4250
+ * @memberOf _
4251
+ * @since 0.1.0
4252
+ * @category Function
4253
+ * @param {Function} func The function to have its output memoized.
4254
+ * @param {Function} [resolver] The function to resolve the cache key.
4255
+ * @returns {Function} Returns the new memoized function.
4256
+ * @example
4257
+ *
4258
+ * var object = { 'a': 1, 'b': 2 };
4259
+ * var other = { 'c': 3, 'd': 4 };
4260
+ *
4261
+ * var values = _.memoize(_.values);
4262
+ * values(object);
4263
+ * // => [1, 2]
4264
+ *
4265
+ * values(other);
4266
+ * // => [3, 4]
4267
+ *
4268
+ * object.a = 2;
4269
+ * values(object);
4270
+ * // => [1, 2]
4271
+ *
4272
+ * // Modify the result cache.
4273
+ * values.cache.set(object, ['a', 'b']);
4274
+ * values(object);
4275
+ * // => ['a', 'b']
4276
+ *
4277
+ * // Replace `_.memoize.Cache`.
4278
+ * _.memoize.Cache = WeakMap;
4279
+ */
4280
+ function memoize$1(func, resolver) {
4281
+ if (typeof func != 'function' || resolver != null && typeof resolver != 'function') {
4282
+ throw new TypeError(FUNC_ERROR_TEXT);
4283
+ }
4284
+ var memoized = function () {
4285
+ var args = arguments,
4286
+ key = resolver ? resolver.apply(this, args) : args[0],
4287
+ cache = memoized.cache;
4288
+ if (cache.has(key)) {
4289
+ return cache.get(key);
4290
+ }
4291
+ var result = func.apply(this, args);
4292
+ memoized.cache = cache.set(key, result) || cache;
4293
+ return result;
4294
+ };
4295
+ memoized.cache = new (memoize$1.Cache || MapCache)();
4296
+ return memoized;
4297
+ }
4298
+
4299
+ // Expose `MapCache`.
4300
+ memoize$1.Cache = MapCache;
4301
+ var memoize_1 = memoize$1;
4302
+ var memoize = memoize_1;
4303
+
4304
+ /** Used as the maximum memoize cache size. */
4305
+ var MAX_MEMOIZE_SIZE = 500;
4306
+
4307
+ /**
4308
+ * A specialized version of `_.memoize` which clears the memoized function's
4309
+ * cache when it exceeds `MAX_MEMOIZE_SIZE`.
4310
+ *
4311
+ * @private
4312
+ * @param {Function} func The function to have its output memoized.
4313
+ * @returns {Function} Returns the new memoized function.
4314
+ */
4315
+ function memoizeCapped$1(func) {
4316
+ var result = memoize(func, function (key) {
4317
+ if (cache.size === MAX_MEMOIZE_SIZE) {
4318
+ cache.clear();
4319
+ }
4320
+ return key;
4321
+ });
4322
+ var cache = result.cache;
4323
+ return result;
4324
+ }
4325
+ var _memoizeCapped = memoizeCapped$1;
4326
+ var memoizeCapped = _memoizeCapped;
4327
+
4328
+ /** Used to match property names within property paths. */
4329
+ var rePropName = /[^.[\]]+|\[(?:(-?\d+(?:\.\d+)?)|(["'])((?:(?!\2)[^\\]|\\.)*?)\2)\]|(?=(?:\.|\[\])(?:\.|\[\]|$))/g;
4330
+
4331
+ /** Used to match backslashes in property paths. */
4332
+ var reEscapeChar = /\\(\\)?/g;
4333
+
4334
+ /**
4335
+ * Converts `string` to a property path array.
4336
+ *
4337
+ * @private
4338
+ * @param {string} string The string to convert.
4339
+ * @returns {Array} Returns the property path array.
4340
+ */
4341
+ var stringToPath$1 = memoizeCapped(function (string) {
4342
+ var result = [];
4343
+ if (string.charCodeAt(0) === 46 /* . */) {
4344
+ result.push('');
4345
+ }
4346
+ string.replace(rePropName, function (match, number, quote, subString) {
4347
+ result.push(quote ? subString.replace(reEscapeChar, '$1') : number || match);
4348
+ });
4349
+ return result;
4350
+ });
4351
+ var _stringToPath = stringToPath$1;
4352
+
4353
+ /**
4354
+ * A specialized version of `_.map` for arrays without support for iteratee
4355
+ * shorthands.
4356
+ *
4357
+ * @private
4358
+ * @param {Array} [array] The array to iterate over.
4359
+ * @param {Function} iteratee The function invoked per iteration.
4360
+ * @returns {Array} Returns the new mapped array.
4361
+ */
4362
+
4363
+ function arrayMap$1(array, iteratee) {
4364
+ var index = -1,
4365
+ length = array == null ? 0 : array.length,
4366
+ result = Array(length);
4367
+ while (++index < length) {
4368
+ result[index] = iteratee(array[index], index, array);
4369
+ }
4370
+ return result;
4371
+ }
4372
+ var _arrayMap = arrayMap$1;
4373
+ var Symbol = _Symbol,
4374
+ arrayMap = _arrayMap,
4375
+ isArray$1 = isArray_1,
4376
+ isSymbol$1 = isSymbol_1;
4377
+
4378
+ /** Used as references for various `Number` constants. */
4379
+ var INFINITY$1 = 1 / 0;
4380
+
4381
+ /** Used to convert symbols to primitives and strings. */
4382
+ var symbolProto = Symbol ? Symbol.prototype : undefined,
4383
+ symbolToString = symbolProto ? symbolProto.toString : undefined;
4384
+
4385
+ /**
4386
+ * The base implementation of `_.toString` which doesn't convert nullish
4387
+ * values to empty strings.
4388
+ *
4389
+ * @private
4390
+ * @param {*} value The value to process.
4391
+ * @returns {string} Returns the string.
4392
+ */
4393
+ function baseToString$1(value) {
4394
+ // Exit early for strings to avoid a performance hit in some environments.
4395
+ if (typeof value == 'string') {
4396
+ return value;
4397
+ }
4398
+ if (isArray$1(value)) {
4399
+ // Recursively convert values (susceptible to call stack limits).
4400
+ return arrayMap(value, baseToString$1) + '';
4401
+ }
4402
+ if (isSymbol$1(value)) {
4403
+ return symbolToString ? symbolToString.call(value) : '';
4404
+ }
4405
+ var result = value + '';
4406
+ return result == '0' && 1 / value == -INFINITY$1 ? '-0' : result;
4407
+ }
4408
+ var _baseToString = baseToString$1;
4409
+ var baseToString = _baseToString;
4410
+
4411
+ /**
4412
+ * Converts `value` to a string. An empty string is returned for `null`
4413
+ * and `undefined` values. The sign of `-0` is preserved.
4414
+ *
4415
+ * @static
4416
+ * @memberOf _
4417
+ * @since 4.0.0
4418
+ * @category Lang
4419
+ * @param {*} value The value to convert.
4420
+ * @returns {string} Returns the converted string.
4421
+ * @example
4422
+ *
4423
+ * _.toString(null);
4424
+ * // => ''
4425
+ *
4426
+ * _.toString(-0);
4427
+ * // => '-0'
4428
+ *
4429
+ * _.toString([1, 2, 3]);
4430
+ * // => '1,2,3'
4431
+ */
4432
+ function toString$1(value) {
4433
+ return value == null ? '' : baseToString(value);
4434
+ }
4435
+ var toString_1 = toString$1;
4436
+ var isArray = isArray_1,
4437
+ isKey = _isKey,
4438
+ stringToPath = _stringToPath,
4439
+ toString = toString_1;
4440
+
4441
+ /**
4442
+ * Casts `value` to a path array if it's not one.
4443
+ *
4444
+ * @private
4445
+ * @param {*} value The value to inspect.
4446
+ * @param {Object} [object] The object to query keys on.
4447
+ * @returns {Array} Returns the cast property path array.
4448
+ */
4449
+ function castPath$1(value, object) {
4450
+ if (isArray(value)) {
4451
+ return value;
4452
+ }
4453
+ return isKey(value, object) ? [value] : stringToPath(toString(value));
4454
+ }
4455
+ var _castPath = castPath$1;
4456
+ var isSymbol = isSymbol_1;
4457
+
4458
+ /** Used as references for various `Number` constants. */
4459
+ var INFINITY = 1 / 0;
4460
+
4461
+ /**
4462
+ * Converts `value` to a string key if it's not a string or symbol.
4463
+ *
4464
+ * @private
4465
+ * @param {*} value The value to inspect.
4466
+ * @returns {string|symbol} Returns the key.
4467
+ */
4468
+ function toKey$1(value) {
4469
+ if (typeof value == 'string' || isSymbol(value)) {
4470
+ return value;
4471
+ }
4472
+ var result = value + '';
4473
+ return result == '0' && 1 / value == -INFINITY ? '-0' : result;
4474
+ }
4475
+ var _toKey = toKey$1;
4476
+ var castPath = _castPath,
4477
+ toKey = _toKey;
4478
+
4479
+ /**
4480
+ * The base implementation of `_.get` without support for default values.
4481
+ *
4482
+ * @private
4483
+ * @param {Object} object The object to query.
4484
+ * @param {Array|string} path The path of the property to get.
4485
+ * @returns {*} Returns the resolved value.
4486
+ */
4487
+ function baseGet$1(object, path) {
4488
+ path = castPath(path, object);
4489
+ var index = 0,
4490
+ length = path.length;
4491
+ while (object != null && index < length) {
4492
+ object = object[toKey(path[index++])];
4493
+ }
4494
+ return index && index == length ? object : undefined;
4495
+ }
4496
+ var _baseGet = baseGet$1;
4497
+ var baseGet = _baseGet;
4498
+
4499
+ /**
4500
+ * Gets the value at `path` of `object`. If the resolved value is
4501
+ * `undefined`, the `defaultValue` is returned in its place.
4502
+ *
4503
+ * @static
4504
+ * @memberOf _
4505
+ * @since 3.7.0
4506
+ * @category Object
4507
+ * @param {Object} object The object to query.
4508
+ * @param {Array|string} path The path of the property to get.
4509
+ * @param {*} [defaultValue] The value returned for `undefined` resolved values.
4510
+ * @returns {*} Returns the resolved value.
4511
+ * @example
4512
+ *
4513
+ * var object = { 'a': [{ 'b': { 'c': 3 } }] };
4514
+ *
4515
+ * _.get(object, 'a[0].b.c');
4516
+ * // => 3
4517
+ *
4518
+ * _.get(object, ['a', '0', 'b', 'c']);
4519
+ * // => 3
4520
+ *
4521
+ * _.get(object, 'a.b.c', 'default');
4522
+ * // => 'default'
4523
+ */
4524
+ function get(object, path, defaultValue) {
4525
+ var result = object == null ? undefined : baseGet(object, path);
4526
+ return result === undefined ? defaultValue : result;
4527
+ }
4528
+ var get_1 = get;
4529
+ var get$1 = /*@__PURE__*/getDefaultExportFromCjs(get_1);
4530
+ const getLanguageParams = (select, document) => {
4531
+ if (!select || !document) {
4532
+ return {};
4533
+ }
4534
+ const selection = select || {};
4535
+ const selectedValue = {};
4536
+ for (const [key, path] of Object.entries(selection)) {
4537
+ let value = get$1(document, path);
4538
+ if (Array.isArray(value)) {
4539
+ value = value.filter(item => typeof item === "object" ? (item == null ? void 0 : item._type) !== "reference" || "_ref" in item : true);
4540
+ }
4541
+ selectedValue[key] = value;
4542
+ }
4543
+ return selectedValue;
4544
+ };
4545
+ const toFieldLanguagesKeyPrefix = "sanityStudio:assist:field-languages:from:";
4546
+ function getPreferredToFieldLanguages(fromLanguageId) {
4547
+ if (typeof localStorage === "undefined") {
4548
+ return [];
4549
+ }
4550
+ const value = localStorage.getItem("".concat(toFieldLanguagesKeyPrefix).concat(fromLanguageId));
4551
+ return value ? JSON.parse(value) : [];
4552
+ }
4553
+ function setPreferredToFieldLanguages(fromLanguageId, languageIds) {
4554
+ if (typeof localStorage === "undefined") {
4555
+ return;
4556
+ }
4557
+ localStorage.setItem("".concat(toFieldLanguagesKeyPrefix).concat(fromLanguageId), JSON.stringify(languageIds));
4558
+ }
4559
+ const FieldTranslationContext = createContext({
4560
+ openFieldTranslation: () => {},
4561
+ translationLoading: false
4562
+ });
4563
+ function useFieldTranslation() {
4564
+ return useContext(FieldTranslationContext);
4565
+ }
4566
+ function hasValuesToTranslate(fieldLanguageMaps, fromLanguage, basePath) {
4567
+ return fieldLanguageMaps == null ? void 0 : fieldLanguageMaps.some(map => map.inputLanguageId === (fromLanguage == null ? void 0 : fromLanguage.id) && map.inputPath && pathToString(map.inputPath).startsWith(pathToString(basePath)));
4568
+ }
4569
+ function FieldTranslationProvider(props) {
4570
+ var _a, _b, _c;
4571
+ const {
4572
+ config: assistConfig
4573
+ } = useAiAssistanceConfig();
4574
+ const apiClient = useApiClient(assistConfig.__customApiClient);
4575
+ const config = (_a = assistConfig.translate) == null ? void 0 : _a.field;
4576
+ const {
4577
+ translate: runTranslate
4578
+ } = useTranslate(apiClient);
4579
+ const [dialogOpen, setDialogOpen] = useState(false);
4580
+ const [fieldTranslationParams, setFieldTranslationParams] = useState();
4581
+ const [languages, setLanguages] = useState();
4582
+ const [fromLanguage, setFromLanguage] = useState(void 0);
4583
+ const [toLanguages, setToLanguages] = useState(void 0);
4584
+ const [fieldLanguageMaps, setFieldLanguageMaps] = useState();
4585
+ const close = useCallback(() => {
4586
+ setDialogOpen(false);
4587
+ setLanguages(void 0);
4588
+ setFieldTranslationParams(void 0);
4589
+ }, []);
4590
+ const languageClient = useClient({
4591
+ apiVersion: (_b = config == null ? void 0 : config.apiVersion) != null ? _b : "2022-11-27"
4592
+ });
4593
+ const documentId = (_c = fieldTranslationParams == null ? void 0 : fieldTranslationParams.document) == null ? void 0 : _c._id;
4594
+ const id = useId();
4595
+ const selectFromLanguage = useCallback((from, languages2, params) => {
4596
+ var _a2, _b2;
4597
+ const {
4598
+ document,
4599
+ documentSchema
4600
+ } = params != null ? params : {};
4601
+ setFromLanguage(from);
4602
+ if (!document || !documentSchema || !params || !languages2) {
4603
+ setFieldLanguageMaps(void 0);
4604
+ return;
4605
+ }
4606
+ const preferred = getPreferredToFieldLanguages(from.id);
4607
+ const allToLanguages = languages2.filter(l => l.id !== (from == null ? void 0 : from.id));
4608
+ const filteredToLanguages = allToLanguages.filter(l => !preferred.length || preferred.includes(l.id));
4609
+ setToLanguages(filteredToLanguages);
4610
+ const fromId = from == null ? void 0 : from.id;
4611
+ const allToIds = (_a2 = allToLanguages == null ? void 0 : allToLanguages.map(l => l.id)) != null ? _a2 : [];
4612
+ const docMembers = getDocumentMembersFlat(document, documentSchema);
4613
+ if (fromId && (allToIds == null ? void 0 : allToIds.length)) {
4614
+ const transMap = getFieldLanguageMap(documentSchema, docMembers, fromId, allToIds.filter(toId => fromId !== toId), (_b2 = config == null ? void 0 : config.translationOutputs) != null ? _b2 : defaultLanguageOutputs);
4615
+ setFieldLanguageMaps(transMap);
4616
+ } else {
4617
+ setFieldLanguageMaps(void 0);
4618
+ }
4619
+ }, [config]);
4620
+ const toggleToLanguage = useCallback((toggledLang, toLanguages2, languages2) => {
4621
+ if (!languages2 || !fromLanguage) {
4622
+ return;
4623
+ }
4624
+ const wasSelected = !!(toLanguages2 == null ? void 0 : toLanguages2.find(l => l.id === toggledLang.id));
4625
+ const newToLangs = languages2.filter(anyLang => !!(toLanguages2 == null ? void 0 : toLanguages2.find(selectedLang => toggledLang.id !== selectedLang.id && selectedLang.id === anyLang.id)) || toggledLang.id === anyLang.id && !wasSelected);
4626
+ setToLanguages(newToLangs);
4627
+ setPreferredToFieldLanguages(fromLanguage.id, newToLangs.map(l => l.id));
4628
+ }, [fromLanguage]);
4629
+ const openFieldTranslation = useCallback(async params => {
4630
+ setDialogOpen(true);
4631
+ const languageParams = getLanguageParams(config == null ? void 0 : config.selectLanguageParams, params.document);
4632
+ const languages2 = await (typeof (config == null ? void 0 : config.languages) === "function" ? config == null ? void 0 : config.languages(languageClient, languageParams) : Promise.resolve(config == null ? void 0 : config.languages));
4633
+ setLanguages(languages2);
4634
+ setFieldTranslationParams(params);
4635
+ const fromLanguage2 = languages2 == null ? void 0 : languages2[0];
4636
+ if (fromLanguage2) {
4637
+ selectFromLanguage(fromLanguage2, languages2, params);
4638
+ } else {
4639
+ console.error("No languages available for selected language params", languageParams);
4640
+ }
4641
+ }, [selectFromLanguage, config, languageClient]);
4642
+ const contextValue = useMemo(() => {
4643
+ return {
4644
+ openFieldTranslation,
4645
+ translationLoading: false
4646
+ };
4647
+ }, [openFieldTranslation]);
4648
+ const runDisabled = !fromLanguage || !(toLanguages == null ? void 0 : toLanguages.length) || !(fieldLanguageMaps == null ? void 0 : fieldLanguageMaps.length) || !documentId || !hasValuesToTranslate(fieldLanguageMaps, fromLanguage, fieldTranslationParams.translatePath);
4649
+ const onRunTranslation = useCallback(() => {
4650
+ const translatePath = fieldTranslationParams == null ? void 0 : fieldTranslationParams.translatePath;
4651
+ if (fieldLanguageMaps && documentId && translatePath) {
4652
+ runTranslate({
4653
+ documentId,
4654
+ translatePath,
4655
+ fieldLanguageMap: fieldLanguageMaps.map(map => ({
4656
+ ...map,
4657
+ // eslint-disable-next-line max-nested-callbacks
4658
+ outputs: map.outputs.filter(out => !!(toLanguages == null ? void 0 : toLanguages.find(l => l.id === out.id)))
4659
+ })),
4660
+ conditionalMembers: fieldTranslationParams == null ? void 0 : fieldTranslationParams.conditionalMembers
4661
+ });
4662
+ }
4663
+ close();
4664
+ }, [fieldLanguageMaps, documentId, runTranslate, close, toLanguages, fieldTranslationParams == null ? void 0 : fieldTranslationParams.translatePath, fieldTranslationParams == null ? void 0 : fieldTranslationParams.conditionalMembers]);
4665
+ const runButton = /* @__PURE__ */jsx(Button, {
4666
+ text: "Translate",
4667
+ tone: "primary",
4668
+ icon: PlayIcon,
4669
+ style: {
4670
+ width: "100%"
4671
+ },
4672
+ disabled: runDisabled,
4673
+ onClick: onRunTranslation
4674
+ });
4675
+ return /* @__PURE__ */jsxs(FieldTranslationContext.Provider, {
4676
+ value: contextValue,
4677
+ children: [dialogOpen ? /* @__PURE__ */jsx(Dialog, {
4678
+ id,
4679
+ width: 1,
4680
+ open: dialogOpen,
4681
+ onClose: close,
4682
+ header: "Translate fields",
4683
+ footer: /* @__PURE__ */jsx(Flex, {
4684
+ justify: "space-between",
4685
+ padding: 2,
4686
+ flex: 1,
4687
+ children: runDisabled ? /* @__PURE__ */jsx(Tooltip, {
4688
+ content: /* @__PURE__ */jsx(Flex, {
4689
+ padding: 2,
4690
+ children: /* @__PURE__ */jsx(Text, {
4691
+ children: "There is nothing to translate in the selected from-language."
4692
+ })
4693
+ }),
4694
+ placement: "top",
4695
+ children: /* @__PURE__ */jsx(Flex, {
4696
+ flex: 1,
4697
+ children: runButton
3216
4698
  })
4699
+ }) : runButton
4700
+ }),
4701
+ children: languages ? /* @__PURE__ */jsxs(Flex, {
4702
+ padding: 4,
4703
+ gap: 5,
4704
+ align: "flex-start",
4705
+ justify: "center",
4706
+ children: [/* @__PURE__ */jsxs(Stack, {
4707
+ space: 2,
4708
+ children: [/* @__PURE__ */jsx(Box, {
4709
+ marginBottom: 2,
4710
+ children: /* @__PURE__ */jsx(Text, {
4711
+ weight: "semibold",
4712
+ children: "From"
4713
+ })
4714
+ }), languages == null ? void 0 : languages.map(radioLanguage => /* @__PURE__ */jsx(FromLanguageRadio, {
4715
+ ...{
4716
+ radioLanguage,
4717
+ fromLanguage,
4718
+ selectFromLanguage,
4719
+ languages,
4720
+ fieldTranslationParams
4721
+ }
4722
+ }, radioLanguage.id))]
4723
+ }), /* @__PURE__ */jsxs(Stack, {
4724
+ space: 2,
4725
+ children: [/* @__PURE__ */jsx(Box, {
4726
+ marginBottom: 2,
4727
+ children: /* @__PURE__ */jsx(Text, {
4728
+ weight: "semibold",
4729
+ children: "To"
4730
+ })
4731
+ }), languages.map(checkboxLanguage => /* @__PURE__ */jsx(ToLanguageCheckbox, {
4732
+ ...{
4733
+ checkboxLanguage,
4734
+ fromLanguage,
4735
+ toLanguages,
4736
+ toggleToLanguage,
4737
+ languages
4738
+ }
4739
+ }, checkboxLanguage.id))]
4740
+ })]
4741
+ }) : /* @__PURE__ */jsxs(Flex, {
4742
+ padding: 4,
4743
+ gap: 2,
4744
+ align: "flex-start",
4745
+ justify: "center",
4746
+ children: [/* @__PURE__ */jsx(Box, {
4747
+ children: /* @__PURE__ */jsx(Spinner, {})
4748
+ }), /* @__PURE__ */jsx(Text, {
4749
+ children: "Loading languages..."
3217
4750
  })]
3218
4751
  })
4752
+ }) : null, props.children]
4753
+ });
4754
+ }
4755
+ function ToLanguageCheckbox(props) {
4756
+ var _a;
4757
+ const {
4758
+ checkboxLanguage,
4759
+ fromLanguage,
4760
+ toLanguages,
4761
+ toggleToLanguage,
4762
+ languages
4763
+ } = props;
4764
+ const langId = checkboxLanguage.id;
4765
+ const onChange = useCallback(() => toggleToLanguage(checkboxLanguage, toLanguages, languages), [toggleToLanguage, checkboxLanguage, toLanguages, languages]);
4766
+ return /* @__PURE__ */jsxs(Flex, {
4767
+ gap: 3,
4768
+ align: "center",
4769
+ as: "label",
4770
+ style: langId === (fromLanguage == null ? void 0 : fromLanguage.id) ? {
4771
+ opacity: 0.5
4772
+ } : void 0,
4773
+ children: [/* @__PURE__ */jsx(Checkbox, {
4774
+ name: "toLang",
4775
+ value: langId,
4776
+ checked: langId !== (fromLanguage == null ? void 0 : fromLanguage.id) && !!(toLanguages == null ? void 0 : toLanguages.find(tl => tl.id === langId)),
4777
+ onChange,
4778
+ disabled: langId === (fromLanguage == null ? void 0 : fromLanguage.id)
4779
+ }), /* @__PURE__ */jsx(Text, {
4780
+ muted: langId === (fromLanguage == null ? void 0 : fromLanguage.id),
4781
+ children: (_a = checkboxLanguage.title) != null ? _a : langId
3219
4782
  })]
4783
+ }, langId);
4784
+ }
4785
+ function FromLanguageRadio(props) {
4786
+ var _a;
4787
+ const {
4788
+ languages,
4789
+ radioLanguage,
4790
+ selectFromLanguage,
4791
+ fromLanguage,
4792
+ fieldTranslationParams
4793
+ } = props;
4794
+ const langId = radioLanguage.id;
4795
+ const onChange = useCallback(() => selectFromLanguage(radioLanguage, languages, fieldTranslationParams), [selectFromLanguage, radioLanguage, languages, fieldTranslationParams]);
4796
+ return /* @__PURE__ */jsxs(Flex, {
4797
+ gap: 3,
4798
+ align: "center",
4799
+ as: "label",
4800
+ children: [/* @__PURE__ */jsx(Radio, {
4801
+ name: "fromLang",
4802
+ value: langId,
4803
+ checked: langId === (fromLanguage == null ? void 0 : fromLanguage.id),
4804
+ onChange
4805
+ }), /* @__PURE__ */jsx(Text, {
4806
+ children: (_a = radioLanguage.title) != null ? _a : radioLanguage.id
4807
+ })]
4808
+ }, langId);
4809
+ }
4810
+ function AssistLayout(props) {
4811
+ const [connectors, setConnectors] = useState([]);
4812
+ return /* @__PURE__ */jsx(AiAssistanceConfigProvider, {
4813
+ config: props.config,
4814
+ children: /* @__PURE__ */jsx(RunInstructionProvider, {
4815
+ children: /* @__PURE__ */jsx(FieldTranslationProvider, {
4816
+ children: /* @__PURE__ */jsxs(ConnectorsProvider, {
4817
+ onConnectorsChange: setConnectors,
4818
+ children: [props.renderDefault(props), /* @__PURE__ */jsx(ThemeProvider, {
4819
+ tone: "default",
4820
+ children: /* @__PURE__ */jsx(AssistConnectorsOverlay, {
4821
+ connectors
4822
+ })
4823
+ })]
4824
+ })
4825
+ })
4826
+ })
3220
4827
  });
3221
4828
  }
3222
4829
  var __freeze$1 = Object.freeze;
@@ -3242,7 +4849,10 @@ function ErrorWrapper(props) {
3242
4849
  const catchError = useCallback(params => {
3243
4850
  setError(params.error);
3244
4851
  }, [setError]);
3245
- const unsetValue = useCallback(() => onChange(PatchEvent.from(unset())), [onChange]);
4852
+ const unsetValue = useCallback(() => {
4853
+ onChange(PatchEvent.from(unset()));
4854
+ setError(void 0);
4855
+ }, [onChange]);
3246
4856
  const dismiss = useCallback(() => setError(void 0), []);
3247
4857
  const catcher = /* @__PURE__ */jsx(ErrorBoundary, {
3248
4858
  onCatch: catchError,
@@ -3310,6 +4920,7 @@ function AssistFormBlock(props) {
3310
4920
  _key: key
3311
4921
  }));
3312
4922
  }, [onChange, key]);
4923
+ const singlePresence = presence[0];
3313
4924
  return /* @__PURE__ */jsx(ErrorWrapper, {
3314
4925
  onChange: localOnChange,
3315
4926
  children: /* @__PURE__ */jsxs(Flex, {
@@ -3318,9 +4929,9 @@ function AssistFormBlock(props) {
3318
4929
  children: [/* @__PURE__ */jsx(Box, {
3319
4930
  flex: 1,
3320
4931
  children: props.renderDefault(props)
3321
- }), presence.map(pre => /* @__PURE__ */jsx(AiFieldPresence, {
3322
- presence: pre
3323
- }, pre.lastActiveAt))]
4932
+ }), singlePresence && /* @__PURE__ */jsx(AiFieldPresence, {
4933
+ presence: singlePresence
4934
+ })]
3324
4935
  })
3325
4936
  });
3326
4937
  }
@@ -3364,16 +4975,24 @@ function InstructionInput(props) {
3364
4975
  ...props
3365
4976
  }), /* @__PURE__ */jsx(ShareField, {
3366
4977
  ...props
3367
- }), /* @__PURE__ */jsx(PromptField, {
4978
+ }), /* @__PURE__ */jsx(ObjectMember, {
4979
+ fieldName: "prompt",
4980
+ ...props
4981
+ }), /* @__PURE__ */jsx(ObjectMember, {
4982
+ fieldName: "output",
3368
4983
  ...props
3369
4984
  })]
3370
4985
  });
3371
4986
  }
3372
- function PromptField(props) {
3373
- const promptMember = findFieldMember(props.members, "prompt");
3374
- return promptMember ? /* @__PURE__ */jsx(ObjectInputMember, {
4987
+ function ObjectMember(_ref13) {
4988
+ let {
4989
+ fieldName,
4990
+ ...props
4991
+ } = _ref13;
4992
+ const member = findFieldMember(props.members, fieldName);
4993
+ return member ? /* @__PURE__ */jsx(ObjectInputMember, {
3375
4994
  ...props,
3376
- member: promptMember
4995
+ member
3377
4996
  }) : null;
3378
4997
  }
3379
4998
  const NONE = [];
@@ -3508,8 +5127,8 @@ function IconInput(props) {
3508
5127
  onChange
3509
5128
  } = props;
3510
5129
  const id = useId();
3511
- const items = useMemo(() => Object.entries(icons).map(_ref10 => {
3512
- let [key, icon] = _ref10;
5130
+ const items = useMemo(() => Object.entries(icons).map(_ref14 => {
5131
+ let [key, icon] = _ref14;
3513
5132
  return /* @__PURE__ */jsx(IconItem, {
3514
5133
  iconKey: key,
3515
5134
  icon,
@@ -3537,12 +5156,12 @@ function IconInput(props) {
3537
5156
  }
3538
5157
  });
3539
5158
  }
3540
- function IconItem(_ref11) {
5159
+ function IconItem(_ref15) {
3541
5160
  let {
3542
5161
  icon,
3543
5162
  iconKey: key,
3544
5163
  onChange
3545
- } = _ref11;
5164
+ } = _ref15;
3546
5165
  const onClick = useCallback(() => onChange(set(key)), [onChange, key]);
3547
5166
  return /* @__PURE__ */jsx(MenuItem, {
3548
5167
  icon,
@@ -3553,8 +5172,8 @@ function IconItem(_ref11) {
3553
5172
  }
3554
5173
  function getIcon(iconName) {
3555
5174
  var _a, _b;
3556
- return (_b = (_a = Object.entries(icons).find(_ref12 => {
3557
- let [key] = _ref12;
5175
+ return (_b = (_a = Object.entries(icons).find(_ref16 => {
5176
+ let [key] = _ref16;
3558
5177
  return key === iconName;
3559
5178
  })) == null ? void 0 : _a[1]) != null ? _b : icons.sparkles;
3560
5179
  }
@@ -3713,11 +5332,11 @@ const contextDocumentSchema = defineType({
3713
5332
  title: "title",
3714
5333
  context: "context"
3715
5334
  },
3716
- prepare(_ref13) {
5335
+ prepare(_ref17) {
3717
5336
  let {
3718
5337
  title,
3719
5338
  context
3720
- } = _ref13;
5339
+ } = _ref17;
3721
5340
  var _a;
3722
5341
  const text = context == null ? void 0 : context.flatMap(block => block == null ? void 0 : block.children).flatMap(child => {
3723
5342
  var _a2;
@@ -3736,7 +5355,11 @@ const contextDocumentSchema = defineType({
3736
5355
  // Strict ESM env, designed to run outside Node.js in envs that provide WebCrypto (deno, browsers, etc)
3737
5356
 
3738
5357
  function getRandomValues(typedArray) {
3739
- return window.crypto.getRandomValues(typedArray);
5358
+ const crypto = typeof window !== 'undefined' && 'crypto' in window ? window.crypto : globalThis.crypto;
5359
+ if (!crypto || !crypto.getRandomValues) {
5360
+ throw new Error('WebCrypto not available in this environment');
5361
+ }
5362
+ return crypto.getRandomValues(typedArray);
3740
5363
  }
3741
5364
  function whatwgRNG() {
3742
5365
  let length = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 16;
@@ -3803,10 +5426,204 @@ function InstructionsArrayField(props) {
3803
5426
  title: " "
3804
5427
  });
3805
5428
  }
5429
+ function InstructionOutputField(props) {
5430
+ var _a;
5431
+ const {
5432
+ fieldSchema
5433
+ } = (_a = useContext(SelectedFieldContext)) != null ? _a : {};
5434
+ if (!fieldSchema || !(isObjectSchemaType(fieldSchema) || isArrayOfObjectsSchemaType(fieldSchema))) {
5435
+ return null;
5436
+ }
5437
+ return /* @__PURE__ */jsx(EnabledOutputField, {
5438
+ ...props,
5439
+ fieldSchema,
5440
+ children: props.children
5441
+ });
5442
+ }
5443
+ function EnabledOutputField(_ref18) {
5444
+ let {
5445
+ fieldSchema,
5446
+ ...props
5447
+ } = _ref18;
5448
+ var _a;
5449
+ const [open, setOpen] = useState(!!((_a = props.value) == null ? void 0 : _a.length));
5450
+ const onExpand = useCallback(() => setOpen(true), []);
5451
+ const onCollapse = useCallback(() => setOpen(false), []);
5452
+ return props.renderDefault({
5453
+ ...props,
5454
+ collapsible: true,
5455
+ onExpand,
5456
+ onCollapse,
5457
+ collapsed: !open,
5458
+ level: 1,
5459
+ title: isObjectSchemaType(fieldSchema) ? "Allowed fields" : "Allowed types"
5460
+ });
5461
+ }
5462
+ function InstructionOutputInput(props) {
5463
+ var _a;
5464
+ const {
5465
+ fieldSchema
5466
+ } = (_a = useContext(SelectedFieldContext)) != null ? _a : {};
5467
+ if (!fieldSchema) {
5468
+ return null;
5469
+ }
5470
+ if (isObjectSchemaType(fieldSchema)) {
5471
+ return /* @__PURE__ */jsx(ObjectOutputInput, {
5472
+ ...props,
5473
+ fieldSchema
5474
+ });
5475
+ }
5476
+ if (isArrayOfObjectsSchemaType(fieldSchema)) {
5477
+ return /* @__PURE__ */jsx(ArrayOutputInput, {
5478
+ ...props,
5479
+ fieldSchema
5480
+ });
5481
+ }
5482
+ return null;
5483
+ }
5484
+ function useEmptySelectAllValue(value, allowedValues, onChange) {
5485
+ useEffect(() => {
5486
+ var _a, _b;
5487
+ const validValues = value == null ? void 0 : value.filter(v => allowedValues.find(f => f.name === (v._type === outputFieldTypeName ? v.relativePath : v.type)));
5488
+ const valueLength = (_a = value == null ? void 0 : value.length) != null ? _a : 0;
5489
+ const validLength = (_b = validValues == null ? void 0 : validValues.length) != null ? _b : 0;
5490
+ if (!validLength && valueLength || validLength >= allowedValues.length) {
5491
+ onChange(PatchEvent.from([unset()]));
5492
+ }
5493
+ }, [allowedValues, value, onChange]);
5494
+ }
5495
+ function ObjectOutputInput(_ref19) {
5496
+ let {
5497
+ fieldSchema,
5498
+ ...props
5499
+ } = _ref19;
5500
+ const {
5501
+ value,
5502
+ onChange
5503
+ } = props;
5504
+ const fields = useMemo(() => fieldSchema.fields.filter(field => isAssistSupported(field.type)), [fieldSchema.fields]);
5505
+ useEmptySelectAllValue(value, fields, onChange);
5506
+ const onSelectChange = useCallback((checked, selectedValue) => {
5507
+ if (checked) {
5508
+ if (value == null ? void 0 : value.length) {
5509
+ onChange(PatchEvent.from(unset([{
5510
+ _key: selectedValue
5511
+ }])));
5512
+ } else {
5513
+ const items = fields.filter(f => f.name !== selectedValue).map(field => typed({
5514
+ _key: field.name,
5515
+ _type: "sanity.assist.output.field",
5516
+ relativePath: field.name
5517
+ }));
5518
+ onChange(PatchEvent.from([setIfMissing([]), insert(items, "after", [-1])]));
5519
+ }
5520
+ } else {
5521
+ const patchValue = {
5522
+ _key: selectedValue,
5523
+ _type: "sanity.assist.output.field",
5524
+ relativePath: selectedValue
5525
+ };
5526
+ onChange(PatchEvent.from([setIfMissing([]), insert([patchValue], "after", [-1])]));
5527
+ }
5528
+ }, [onChange, value, fields]);
5529
+ return /* @__PURE__ */jsx(Stack, {
5530
+ space: 2,
5531
+ children: fields.map(field => {
5532
+ var _a;
5533
+ return /* @__PURE__ */jsx(Flex, {
5534
+ align: "center",
5535
+ gap: 2,
5536
+ children: /* @__PURE__ */jsx(Selectable, {
5537
+ value: field.name,
5538
+ title: (_a = field.type.title) != null ? _a : field.name,
5539
+ arrayValue: value,
5540
+ onChange: onSelectChange
5541
+ })
5542
+ }, field.name);
5543
+ })
5544
+ });
5545
+ }
5546
+ function ArrayOutputInput(_ref20) {
5547
+ let {
5548
+ fieldSchema,
5549
+ ...props
5550
+ } = _ref20;
5551
+ const {
5552
+ value,
5553
+ onChange
5554
+ } = props;
5555
+ const ofItems = useMemo(() => fieldSchema.of.filter(itemType => isAssistSupported(itemType)), [fieldSchema.of]);
5556
+ useEmptySelectAllValue(value, ofItems, onChange);
5557
+ const onSelectChange = useCallback((checked, selectedValue) => {
5558
+ if (checked) {
5559
+ if (value == null ? void 0 : value.length) {
5560
+ onChange(PatchEvent.from(unset([{
5561
+ _key: selectedValue
5562
+ }])));
5563
+ } else {
5564
+ const items = ofItems.filter(f => f.name !== selectedValue).map(field => typed({
5565
+ _key: field.name,
5566
+ _type: "sanity.assist.output.type",
5567
+ type: field.name
5568
+ }));
5569
+ onChange(PatchEvent.from([setIfMissing([]), insert(items, "after", [-1])]));
5570
+ }
5571
+ } else {
5572
+ const patchValue = {
5573
+ _key: selectedValue,
5574
+ _type: "sanity.assist.output.type",
5575
+ type: selectedValue
5576
+ };
5577
+ onChange(PatchEvent.from([setIfMissing([]), insert([patchValue], "after", [-1])]));
5578
+ }
5579
+ }, [onChange, value, ofItems]);
5580
+ return /* @__PURE__ */jsx(Stack, {
5581
+ space: 2,
5582
+ children: ofItems.map(itemType => {
5583
+ var _a;
5584
+ return /* @__PURE__ */jsx(Flex, {
5585
+ children: /* @__PURE__ */jsx(Selectable, {
5586
+ value: itemType.name,
5587
+ title: isType(itemType, "block") ? "Text" : (_a = itemType.title) != null ? _a : itemType.name,
5588
+ arrayValue: value,
5589
+ onChange: onSelectChange
5590
+ })
5591
+ }, itemType.name);
5592
+ })
5593
+ });
5594
+ }
5595
+ function Selectable(_ref21) {
5596
+ let {
5597
+ title,
5598
+ arrayValue,
5599
+ value,
5600
+ onChange
5601
+ } = _ref21;
5602
+ const checked = !(arrayValue == null ? void 0 : arrayValue.length) || !!(arrayValue == null ? void 0 : arrayValue.find(v => v._key === value));
5603
+ const handleChange = useCallback(() => onChange(checked, value), [onChange, checked, value]);
5604
+ return /* @__PURE__ */jsxs(Flex, {
5605
+ gap: 2,
5606
+ align: "flex-start",
5607
+ children: [/* @__PURE__ */jsx(Checkbox, {
5608
+ checked,
5609
+ onChange: handleChange
5610
+ }), /* @__PURE__ */jsx(Card, {
5611
+ marginTop: 1,
5612
+ onClick: handleChange,
5613
+ children: /* @__PURE__ */jsx(Text, {
5614
+ style: {
5615
+ cursor: "default"
5616
+ },
5617
+ size: 1,
5618
+ children: title
5619
+ })
5620
+ })]
5621
+ });
5622
+ }
3806
5623
  const fieldReference = defineType({
3807
5624
  type: "object",
3808
5625
  name: fieldReferenceTypeName,
3809
- title: "Document field",
5626
+ title: "Field",
3810
5627
  icon: ThListIcon,
3811
5628
  fields: [defineField({
3812
5629
  type: "string",
@@ -3846,10 +5663,10 @@ const fieldReference = defineType({
3846
5663
  select: {
3847
5664
  path: "path"
3848
5665
  },
3849
- prepare(_ref14) {
5666
+ prepare(_ref22) {
3850
5667
  let {
3851
5668
  path
3852
- } = _ref14;
5669
+ } = _ref22;
3853
5670
  return {
3854
5671
  title: path,
3855
5672
  path,
@@ -3994,12 +5811,12 @@ const instruction = defineType({
3994
5811
  title: "title",
3995
5812
  userId: "userId"
3996
5813
  },
3997
- prepare: _ref15 => {
5814
+ prepare: _ref23 => {
3998
5815
  let {
3999
5816
  icon,
4000
5817
  title,
4001
5818
  userId
4002
- } = _ref15;
5819
+ } = _ref23;
4003
5820
  return {
4004
5821
  title,
4005
5822
  icon: icon ? icons[icon] : SparklesIcon,
@@ -4104,6 +5921,33 @@ const instruction = defineType({
4104
5921
  var _a, _b;
4105
5922
  return (_b = (_a = context.currentUser) == null ? void 0 : _a.id) != null ? _b : "";
4106
5923
  }
5924
+ }), defineField({
5925
+ type: "array",
5926
+ name: "output",
5927
+ title: "Output filter",
5928
+ components: {
5929
+ input: InstructionOutputInput,
5930
+ field: InstructionOutputField
5931
+ },
5932
+ of: [defineArrayMember({
5933
+ type: "object",
5934
+ name: outputFieldTypeName,
5935
+ title: "Output field",
5936
+ fields: [{
5937
+ type: "string",
5938
+ name: "path",
5939
+ title: "Path"
5940
+ }]
5941
+ }), defineArrayMember({
5942
+ type: "object",
5943
+ name: outputTypeTypeName,
5944
+ title: "Output type",
5945
+ fields: [{
5946
+ type: "string",
5947
+ name: "type",
5948
+ title: "Type"
5949
+ }]
5950
+ })]
4107
5951
  })]
4108
5952
  });
4109
5953
  const fieldInstructions = defineType({
@@ -4320,7 +6164,7 @@ function PrivateIcon() {
4320
6164
  children: /* @__PURE__ */jsx(LockIcon, {})
4321
6165
  });
4322
6166
  }
4323
- const ImageContext = createContext(void 0);
6167
+ const ImageContext = createContext({});
4324
6168
  function ImageContextProvider(props) {
4325
6169
  var _a;
4326
6170
  const {
@@ -4335,7 +6179,8 @@ function ImageContextProvider(props) {
4335
6179
  documentSchemaType
4336
6180
  } = useAssistDocumentContext();
4337
6181
  const {
4338
- config
6182
+ config,
6183
+ status
4339
6184
  } = useAiAssistanceConfig();
4340
6185
  const apiClient = useApiClient(config == null ? void 0 : config.__customApiClient);
4341
6186
  const {
@@ -4345,28 +6190,30 @@ function ImageContextProvider(props) {
4345
6190
  isSyncing
4346
6191
  } = useSyncState(publicId(documentId), documentSchemaType.name);
4347
6192
  useEffect(() => {
4348
- const captionField = getCaptionFieldOption(schemaType);
4349
- if (assetRef && documentId && captionField && assetRef !== assetRefState && !isSyncing) {
6193
+ const descriptionField = getDescriptionFieldOption(schemaType);
6194
+ if (assetRef && documentId && descriptionField && assetRef !== assetRefState && !isSyncing && canUseAssist(status)) {
4350
6195
  setAssetRefState(assetRef);
4351
6196
  generateCaption({
4352
- path: pathToString([...path, captionField]),
6197
+ path: pathToString([...path, descriptionField]),
4353
6198
  documentId
4354
6199
  });
4355
6200
  }
4356
- }, [schemaType, path, assetRef, assetRefState, documentId, generateCaption, isSyncing]);
6201
+ }, [schemaType, path, assetRef, assetRefState, documentId, generateCaption, isSyncing, status]);
4357
6202
  const context = useMemo(() => {
4358
- const captionField = getCaptionFieldOption(schemaType);
4359
- return captionField ? {
4360
- captionPath: pathToString([...path, captionField]),
6203
+ const descriptionField = getDescriptionFieldOption(schemaType);
6204
+ const imageInstructionField = getImageInstructionFieldOption(schemaType);
6205
+ return {
6206
+ imageDescriptionPath: descriptionField ? pathToString([...path, descriptionField]) : void 0,
6207
+ imageInstructionPath: imageInstructionField ? pathToString([...path, imageInstructionField]) : void 0,
4361
6208
  assetRef
4362
- } : void 0;
6209
+ };
4363
6210
  }, [schemaType, path, assetRef]);
4364
6211
  return /* @__PURE__ */jsx(ImageContext.Provider, {
4365
6212
  value: context,
4366
6213
  children: props.renderDefault(props)
4367
6214
  });
4368
6215
  }
4369
- function node$1(node2) {
6216
+ function node$3(node2) {
4370
6217
  return node2;
4371
6218
  }
4372
6219
  const generateCaptionsActions = {
@@ -4374,7 +6221,11 @@ const generateCaptionsActions = {
4374
6221
  useAction(props) {
4375
6222
  const pathKey = usePathKey(props.path);
4376
6223
  const {
4377
- config
6224
+ openInspector
6225
+ } = useDocumentPane();
6226
+ const {
6227
+ config,
6228
+ status
4378
6229
  } = useAiAssistanceConfig();
4379
6230
  const apiClient = useApiClient(config == null ? void 0 : config.__customApiClient);
4380
6231
  const {
@@ -4382,12 +6233,12 @@ const generateCaptionsActions = {
4382
6233
  loading
4383
6234
  } = useGenerateCaption(apiClient);
4384
6235
  const imageContext = useContext(ImageContext);
4385
- if (imageContext && pathKey === (imageContext == null ? void 0 : imageContext.captionPath)) {
6236
+ if (imageContext && pathKey === (imageContext == null ? void 0 : imageContext.imageDescriptionPath)) {
4386
6237
  const {
4387
6238
  documentId
4388
6239
  } = useAssistDocumentContext();
4389
6240
  return useMemo(() => {
4390
- return node$1({
6241
+ return node$3({
4391
6242
  type: "action",
4392
6243
  icon: loading ? () => /* @__PURE__ */jsx(Box, {
4393
6244
  style: {
@@ -4399,11 +6250,18 @@ const generateCaptionsActions = {
4399
6250
  }
4400
6251
  })
4401
6252
  }) : ImageIcon,
4402
- title: "Generate caption",
6253
+ title: "Generate image description",
4403
6254
  onAction: () => {
4404
6255
  if (loading) {
4405
6256
  return;
4406
6257
  }
6258
+ if (!canUseAssist(status)) {
6259
+ openInspector(aiInspectorId, {
6260
+ [fieldPathParam]: pathKey,
6261
+ [instructionParam]: void 0
6262
+ });
6263
+ return;
6264
+ }
4407
6265
  generateCaption({
4408
6266
  path: pathKey,
4409
6267
  documentId: documentId != null ? documentId : ""
@@ -4413,7 +6271,186 @@ const generateCaptionsActions = {
4413
6271
  disabled: loading,
4414
6272
  hidden: !imageContext.assetRef
4415
6273
  });
4416
- }, [generateCaption, pathKey, documentId, loading, imageContext]);
6274
+ }, [generateCaption, pathKey, documentId, loading, imageContext, status, openInspector]);
6275
+ }
6276
+ return void 0;
6277
+ }
6278
+ };
6279
+ function node$2(node2) {
6280
+ return node2;
6281
+ }
6282
+ const translateActions = {
6283
+ name: "sanity-assist-translate",
6284
+ useAction(props) {
6285
+ var _a, _b, _c, _d, _e, _f, _g, _h;
6286
+ const {
6287
+ config,
6288
+ status
6289
+ } = useAiAssistanceConfig();
6290
+ const apiClient = useApiClient(config == null ? void 0 : config.__customApiClient);
6291
+ const {
6292
+ schemaType: fieldSchemaType,
6293
+ path,
6294
+ documentId,
6295
+ documentSchemaType,
6296
+ documentIsAssistable
6297
+ } = props;
6298
+ const isDocumentLevel = path.length === 0;
6299
+ const readOnly = fieldSchemaType.readOnly === true;
6300
+ const docTransTypes = (_b = (_a = config.translate) == null ? void 0 : _a.document) == null ? void 0 : _b.documentTypes;
6301
+ const options = fieldSchemaType == null ? void 0 : fieldSchemaType.options;
6302
+ const addFieldAction = isDocumentLevel || ((_c = options == null ? void 0 : options.aiAssist) == null ? void 0 : _c.translateAction);
6303
+ const fieldTransEnabled = addFieldAction && documentSchemaType && ((_f = (_e = (_d = config.translate) == null ? void 0 : _d.field) == null ? void 0 : _e.documentTypes) == null ? void 0 : _f.includes(documentSchemaType.name));
6304
+ const documentTranslationEnabled = addFieldAction && documentSchemaType && (!docTransTypes && isAssistSupported(fieldSchemaType) || (docTransTypes == null ? void 0 : docTransTypes.includes(documentSchemaType.name)));
6305
+ if (documentSchemaType && (documentTranslationEnabled || fieldTransEnabled)) {
6306
+ const {
6307
+ value: documentValue,
6308
+ onChange: documentOnChange,
6309
+ formState
6310
+ } = useDocumentPane();
6311
+ const docRef = useRef(documentValue);
6312
+ docRef.current = documentValue;
6313
+ const formStateRef = useRef(formState);
6314
+ formStateRef.current = formState;
6315
+ const translationApi = useTranslate(apiClient);
6316
+ const translate = useDraftDelayedTask({
6317
+ documentOnChange,
6318
+ isDocAssistable: documentIsAssistable != null ? documentIsAssistable : false,
6319
+ task: translationApi.translate
6320
+ });
6321
+ const languagePath = (_h = (_g = config.translate) == null ? void 0 : _g.document) == null ? void 0 : _h.languageField;
6322
+ const translateDocumentAction = useMemo(() => {
6323
+ if (!languagePath || !documentTranslationEnabled) {
6324
+ return void 0;
6325
+ }
6326
+ const title = path.length ? "Translate" : "Translate document";
6327
+ return node$2({
6328
+ type: "action",
6329
+ icon: translationApi.loading ? () => /* @__PURE__ */jsx(Box, {
6330
+ style: {
6331
+ height: 17
6332
+ },
6333
+ children: /* @__PURE__ */jsx(Spinner, {
6334
+ style: {
6335
+ transform: "translateY(6px)"
6336
+ }
6337
+ })
6338
+ }) : TranslateIcon,
6339
+ title,
6340
+ onAction: () => {
6341
+ if (translationApi.loading || !languagePath || !documentId) {
6342
+ return;
6343
+ }
6344
+ translate({
6345
+ languagePath,
6346
+ translatePath: path,
6347
+ documentId: documentId != null ? documentId : "",
6348
+ conditionalMembers: formStateRef.current ? getConditionalMembers(formStateRef.current) : []
6349
+ });
6350
+ },
6351
+ renderAsButton: true,
6352
+ disabled: translationApi.loading || readOnly
6353
+ });
6354
+ }, [languagePath, translate, documentId, translationApi.loading, documentTranslationEnabled, path, readOnly]);
6355
+ const fieldTranslate = useFieldTranslation();
6356
+ const openFieldTranslation = useDraftDelayedTask({
6357
+ documentOnChange,
6358
+ isDocAssistable: documentIsAssistable != null ? documentIsAssistable : false,
6359
+ task: fieldTranslate.openFieldTranslation
6360
+ });
6361
+ const translateFieldsAction = useMemo(() => fieldTransEnabled ? node$2({
6362
+ type: "action",
6363
+ icon: fieldTranslate.translationLoading ? () => /* @__PURE__ */jsx(Box, {
6364
+ style: {
6365
+ height: 17
6366
+ },
6367
+ children: /* @__PURE__ */jsx(Spinner, {
6368
+ style: {
6369
+ transform: "translateY(6px)"
6370
+ }
6371
+ })
6372
+ }) : TranslateIcon,
6373
+ title: "Translate fields...",
6374
+ onAction: () => {
6375
+ if (fieldTranslate.translationLoading || !documentId) {
6376
+ return;
6377
+ }
6378
+ if (formStateRef.current) {
6379
+ getConditionalMembers(formStateRef.current);
6380
+ }
6381
+ openFieldTranslation({
6382
+ document: docRef.current,
6383
+ documentSchema: documentSchemaType,
6384
+ translatePath: path,
6385
+ conditionalMembers: formStateRef.current ? getConditionalMembers(formStateRef.current) : []
6386
+ });
6387
+ },
6388
+ renderAsButton: true,
6389
+ disabled: fieldTranslate.translationLoading || readOnly
6390
+ }) : void 0, [openFieldTranslation, documentSchemaType, documentId, fieldTranslate.translationLoading, fieldTransEnabled, path, readOnly]);
6391
+ return useMemo(() => {
6392
+ if (!(status == null ? void 0 : status.initialized)) {
6393
+ return void 0;
6394
+ }
6395
+ return node$2({
6396
+ type: "group",
6397
+ icon: () => null,
6398
+ title: "Translation",
6399
+ children: [translateDocumentAction, translateFieldsAction].filter(c => !!c),
6400
+ expanded: true
6401
+ });
6402
+ }, [translateDocumentAction, translateFieldsAction, status]);
6403
+ }
6404
+ return void 0;
6405
+ }
6406
+ };
6407
+ function node$1(node2) {
6408
+ return node2;
6409
+ }
6410
+ const generateImagActions = {
6411
+ name: "sanity-assist-generate-image",
6412
+ useAction(props) {
6413
+ const pathKey = usePathKey(props.path);
6414
+ const {
6415
+ config
6416
+ } = useAiAssistanceConfig();
6417
+ const apiClient = useApiClient(config == null ? void 0 : config.__customApiClient);
6418
+ const {
6419
+ generateImage,
6420
+ loading
6421
+ } = useGenerateImage(apiClient);
6422
+ const imageContext = useContext(ImageContext);
6423
+ if (imageContext && pathKey === (imageContext == null ? void 0 : imageContext.imageInstructionPath)) {
6424
+ const {
6425
+ documentId
6426
+ } = useAssistDocumentContext();
6427
+ return useMemo(() => {
6428
+ return node$1({
6429
+ type: "action",
6430
+ icon: loading ? () => /* @__PURE__ */jsx(Box, {
6431
+ style: {
6432
+ height: 17
6433
+ },
6434
+ children: /* @__PURE__ */jsx(Spinner, {
6435
+ style: {
6436
+ transform: "translateY(6px)"
6437
+ }
6438
+ })
6439
+ }) : ImageIcon,
6440
+ title: "Generate image from prompt",
6441
+ onAction: () => {
6442
+ if (loading) {
6443
+ return;
6444
+ }
6445
+ generateImage({
6446
+ path: pathKey,
6447
+ documentId: documentId != null ? documentId : ""
6448
+ });
6449
+ },
6450
+ renderAsButton: true,
6451
+ disabled: loading
6452
+ });
6453
+ }, [generateImage, pathKey, documentId, loading]);
4417
6454
  }
4418
6455
  return void 0;
4419
6456
  }
@@ -4438,7 +6475,8 @@ const assistFieldActions = {
4438
6475
  documentOnChange,
4439
6476
  documentSchemaType,
4440
6477
  documentId,
4441
- selectedPath
6478
+ selectedPath,
6479
+ assistableDocumentId
4442
6480
  } =
4443
6481
  // document field actions do not have access to the document context
4444
6482
  // conditional hook _should_ be safe here since the logical path will be stable
@@ -4448,8 +6486,11 @@ const assistFieldActions = {
4448
6486
  // eslint-disable-next-line react-hooks/rules-of-hooks
4449
6487
  useAssistDocumentContext();
4450
6488
  const {
4451
- value: docValue
6489
+ value: docValue,
6490
+ formState
4452
6491
  } = useDocumentPane();
6492
+ const formStateRef = useRef(formState);
6493
+ formStateRef.current = formState;
4453
6494
  const currentUser = useCurrentUser();
4454
6495
  const isHidden = !assistDocument;
4455
6496
  const pathKey = usePathKey(props.path);
@@ -4463,7 +6504,7 @@ const assistFieldActions = {
4463
6504
  isDocAssistable: documentIsAssistable != null ? documentIsAssistable : false
4464
6505
  });
4465
6506
  const isSelectable = !!useSelectedField(documentSchemaType, typePath);
4466
- const assistSupported = useAssistSupported(props.path, schemaType) && isSelectable && isSchemaAssistEnabled(documentSchemaType);
6507
+ const assistSupported = useAssistSupported(props.path, schemaType) && isSelectable && isSchemaAssistEnabled(documentSchemaType) && schemaType.readOnly !== true;
4467
6508
  const fieldAssist = useMemo(() => {
4468
6509
  var _a;
4469
6510
  return ((_a = assistDocument == null ? void 0 : assistDocument.fields) != null ? _a : []).find(f => f.path === typePath || pathKey === documentRootKey && f.path === pathKey);
@@ -4473,6 +6514,13 @@ const assistFieldActions = {
4473
6514
  const isPathSelected = pathKey === selectedPath;
4474
6515
  const isSelected = isInspectorOpen && isPathSelected;
4475
6516
  const imageCaptionAction = generateCaptionsActions.useAction(props);
6517
+ const imageGenAction = generateImagActions.useAction(props);
6518
+ const translateAction = translateActions.useAction(typed({
6519
+ ...props,
6520
+ documentId: assistableDocumentId,
6521
+ documentIsAssistable,
6522
+ documentSchemaType
6523
+ }));
4476
6524
  const manageInstructions = useCallback(() => isSelected ? closeInspector(aiInspectorId) : openInspector(aiInspectorId, {
4477
6525
  [fieldPathParam]: pathKey,
4478
6526
  [instructionParam]: void 0
@@ -4486,7 +6534,8 @@ const assistFieldActions = {
4486
6534
  assistDocumentId,
4487
6535
  path: pathKey,
4488
6536
  typePath,
4489
- instruction
6537
+ instruction,
6538
+ conditionalMembers: formStateRef.current ? getConditionalMembers(formStateRef.current) : []
4490
6539
  });
4491
6540
  }, [requestRunInstruction, assistableDocId, pathKey, typePath, assistDocumentId, fieldAssistKey]);
4492
6541
  const privateInstructions = useMemo(() => {
@@ -4499,7 +6548,7 @@ const assistFieldActions = {
4499
6548
  }, [fieldAssist == null ? void 0 : fieldAssist.instructions]);
4500
6549
  const instructions = useMemo(() => [...privateInstructions, ...sharedInstructions], [privateInstructions, sharedInstructions]);
4501
6550
  const runInstructionsGroup = useMemo(() => {
4502
- return (instructions == null ? void 0 : instructions.length) || imageCaptionAction ? node({
6551
+ return (instructions == null ? void 0 : instructions.length) || imageCaptionAction || translateAction || imageGenAction ? node({
4503
6552
  type: "group",
4504
6553
  icon: () => null,
4505
6554
  title: "Run instructions",
@@ -4510,10 +6559,10 @@ const assistFieldActions = {
4510
6559
  hidden: isHidden,
4511
6560
  documentIsNew: !!documentIsNew,
4512
6561
  assistSupported
4513
- }))), imageCaptionAction].filter(Boolean),
6562
+ }))), imageCaptionAction, imageGenAction].filter(a => !!a),
4514
6563
  expanded: true
4515
6564
  }) : void 0;
4516
- }, [instructions, currentUser == null ? void 0 : currentUser.id, onInstructionAction, isHidden, documentIsNew, assistSupported, imageCaptionAction]);
6565
+ }, [instructions, currentUser == null ? void 0 : currentUser.id, onInstructionAction, isHidden, documentIsNew, assistSupported, imageCaptionAction, translateAction, imageGenAction]);
4517
6566
  const instructionsLength = (instructions == null ? void 0 : instructions.length) || 0;
4518
6567
  const manageInstructionsItem = useMemo(() => node({
4519
6568
  type: "action",
@@ -4526,13 +6575,13 @@ const assistFieldActions = {
4526
6575
  type: "group",
4527
6576
  icon: SparklesIcon,
4528
6577
  title: pluginTitleShort,
4529
- children: [runInstructionsGroup, assistSupported && manageInstructionsItem].filter(c => !!c),
6578
+ children: [runInstructionsGroup, translateAction, assistSupported && manageInstructionsItem].filter(c => !!c).filter(c => c.type === "group" ? c.children.length : true),
4530
6579
  expanded: false,
4531
6580
  renderAsButton: true,
4532
- hidden: !assistSupported && !imageCaptionAction
6581
+ hidden: !assistSupported && !imageCaptionAction && !translateAction && !imageGenAction
4533
6582
  }), [
4534
6583
  //documentIsNew,
4535
- runInstructionsGroup, manageInstructionsItem, assistSupported, imageCaptionAction]);
6584
+ runInstructionsGroup, manageInstructionsItem, assistSupported, imageCaptionAction, translateAction, imageGenAction]);
4536
6585
  const emptyAction = useMemo(() => node({
4537
6586
  type: "action",
4538
6587
  hidden: !assistSupported,
@@ -4542,7 +6591,7 @@ const assistFieldActions = {
4542
6591
  title: pluginTitleShort,
4543
6592
  selected: isSelected
4544
6593
  }), [assistSupported, manageInstructions, isSelected]);
4545
- if (instructionsLength === 0 && !imageCaptionAction) {
6594
+ if (instructionsLength === 0 && !imageCaptionAction && !translateAction && !imageGenAction) {
4546
6595
  return emptyAction;
4547
6596
  }
4548
6597
  return group;
@@ -4562,9 +6611,7 @@ function instructionItem(props) {
4562
6611
  iconRight: isPrivate ? PrivateIcon : void 0,
4563
6612
  title: getInstructionTitle(instruction),
4564
6613
  onAction: () => onInstructionAction(instruction),
4565
- disabled: assistSupported ? false : {
4566
- reason: "".concat(pluginTitle, " is not supported for this field")
4567
- },
6614
+ disabled: !assistSupported,
4568
6615
  hidden
4569
6616
  });
4570
6617
  }
@@ -4641,7 +6688,7 @@ function useInstructionToaster(documentId, documentSchemaType) {
4641
6688
  }
4642
6689
  function AssistDocumentInputWrapper(props) {
4643
6690
  var _a;
4644
- if (!isType(props.schemaType, "document") && props.id !== "root") {
6691
+ if (!isType(props.schemaType, "document") && props.id !== "root" && props.id !== assistFormId) {
4645
6692
  return /* @__PURE__ */jsx(AssistInput, {
4646
6693
  ...props
4647
6694
  });
@@ -4655,18 +6702,34 @@ function AssistDocumentInputWrapper(props) {
4655
6702
  documentId
4656
6703
  });
4657
6704
  }
4658
- function AssistDocumentInput(_ref16) {
6705
+ function AssistDocumentInput(_ref24) {
4659
6706
  let {
4660
6707
  documentId,
4661
6708
  ...props
4662
- } = _ref16;
6709
+ } = _ref24;
4663
6710
  useInstructionToaster(documentId, props.schemaType);
6711
+ const schemaType = useMemo(() => {
6712
+ if (props.schemaType.name !== assistDocumentTypeName) {
6713
+ return props.schemaType;
6714
+ }
6715
+ return {
6716
+ ...props.schemaType,
6717
+ type: {
6718
+ ...props.schemaType.type,
6719
+ // compatability with i18nArrays plugin that requires this to be document
6720
+ name: "document"
6721
+ }
6722
+ };
6723
+ }, [props.schemaType]);
4664
6724
  return /* @__PURE__ */jsx(FirstAssistedPathProvider, {
4665
6725
  members: props.members,
4666
6726
  children: /* @__PURE__ */jsx(AssistDocumentContextProvider, {
4667
- schemaType: props.schemaType,
6727
+ schemaType,
4668
6728
  documentId,
4669
- children: props.renderDefault(props)
6729
+ children: props.renderDefault({
6730
+ ...props,
6731
+ schemaType
6732
+ })
4670
6733
  })
4671
6734
  });
4672
6735
  }
@@ -4737,31 +6800,41 @@ const assist = definePlugin(config => {
4737
6800
  schema: {
4738
6801
  types: schemaTypes
4739
6802
  },
6803
+ i18n: {
6804
+ bundles: [{}]
6805
+ },
4740
6806
  document: {
4741
6807
  inspectors: (prev, context) => {
4742
- const docSchema = context.schema.get(context.documentType);
6808
+ const documentType = context.documentType;
6809
+ const docSchema = context.schema.get(documentType);
4743
6810
  if (docSchema && isSchemaAssistEnabled(docSchema)) {
4744
6811
  return [...prev, assistInspector];
4745
6812
  }
4746
6813
  return prev;
4747
6814
  },
4748
- unstable_fieldActions: (prev, _ref17) => {
6815
+ unstable_fieldActions: (prev, _ref25) => {
4749
6816
  let {
4750
6817
  documentType,
4751
6818
  schema
4752
- } = _ref17;
6819
+ } = _ref25;
6820
+ if (documentType === assistDocumentTypeName) {
6821
+ return [];
6822
+ }
4753
6823
  const docSchema = schema.get(documentType);
4754
6824
  if (docSchema && isSchemaAssistEnabled(docSchema)) {
4755
6825
  return [...prev, assistFieldActions];
4756
6826
  }
4757
6827
  return prev;
4758
6828
  },
4759
- unstable_languageFilter: (prev, _ref18) => {
6829
+ unstable_languageFilter: (prev, _ref26) => {
4760
6830
  let {
4761
6831
  documentId,
4762
6832
  schema,
4763
6833
  schemaType
4764
- } = _ref18;
6834
+ } = _ref26;
6835
+ if (schemaType === assistDocumentTypeName) {
6836
+ return [];
6837
+ }
4765
6838
  const docSchema = schema.get(schemaType);
4766
6839
  if (docSchema && isObjectSchemaType(docSchema) && isSchemaAssistEnabled(docSchema)) {
4767
6840
  return [...prev, createAssistDocumentPresence(documentId, docSchema)];
@@ -4815,5 +6888,5 @@ const assist = definePlugin(config => {
4815
6888
  })()]
4816
6889
  };
4817
6890
  });
4818
- export { SchemaTypeTool, assist, contextDocumentTypeName };
6891
+ export { SchemaTypeTool, assist, contextDocumentTypeName, defaultLanguageOutputs };
4819
6892
  //# sourceMappingURL=index.esm.js.map