@sanity/assist 1.2.15-lang.3 → 1.2.15-lang.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -298,24 +298,29 @@ This will add a "Generate caption" action to the configured field.
298
298
  Fields within array items are not supported.
299
299
 
300
300
  ## Image generation
301
-
302
- <img width="600" alt="image" src="https://github.com/sanity-io/assist/assets/835514/c144985c-d828-4e55-8a6d-5d5da033791f">
301
+ <img width="600" alt="image" src="https://github.com/sanity-io/assist/assets/835514/c4de6791-f530-4cd1-b0c2-96ef988bc256">
303
302
 
304
303
  AI Assist can generate assets for images configured with a prompt field.
305
304
 
306
- Whenever the image prompt field is written to by an AI Assist instruction, the field value is used as a prompt to generate a new image.
305
+ An image is generated directly by using the "Generate image from prompt" instruction on the prompt field,
306
+ or indirectly whenever the image prompt field is written to by an AI Assist instruction.
307
307
 
308
+ ### Configure
308
309
  To enable image generation for an image field, the image must:
309
310
  - set `options.imagePromptField` to a child-path relative to the image
310
311
  - have a `string` or `text` field that corresponds to the `imagePromptField` path
311
312
 
312
- Next, create an AI Assist instruction that will visit the image prompt field.
313
+ This will add a "Generate image from prompt" instruction to the image prompt field. Running it will generate and image.
314
+
315
+ Additionally, whenever an AI Assist instruction writes to the image prompt field, the image will be generated.
313
316
 
314
317
  This could be a document instruction, an instruction for the image field or parent object, or directly on the image prompt field.
315
318
 
316
- Use AI context documents to apply a reusable styleguide to images as needed.
319
+ A common styleguide can achieved by adding an instruction to the image prompt field that rewrites whatever value is there, to include a common style.
320
+ Use AI context documents to apply a reusable styleguide to the prompt rewriting as needed.
317
321
 
318
322
  #### Example
323
+
319
324
  Given the following document schema
320
325
  ```ts
321
326
  defineType({
@@ -341,16 +346,19 @@ defineType({
341
346
  })
342
347
  ```
343
348
 
344
- To directly generate an image, run the following instruction on the image prompt field:
345
- "Repeat the value in {Reference to image-prompt-field}".
349
+ To directly generate an image based on the value in the prompt field,
350
+ run the "Generate image from prompt" instruction that is automatically added.
351
+
352
+ For better image results or to ensure a consistent style, rewrite the prompt before generating the image:
346
353
 
347
354
  ### Example prompt expansion instruction
355
+ <img width="267" alt="image" src="https://github.com/sanity-io/assist/assets/835514/dabc6910-80d3-4a69-940f-49ac5cae9ade">
348
356
 
349
357
  For better image results, use an instruction that expands the prompt to be more detailed.
350
358
 
351
359
  Example instruction text:
352
360
 
353
- "
361
+ ```
354
362
  Rewrite image prompts for image generation according to the following rules:
355
363
  - Be Specific: Include detailed descriptions of the scene, objects, colors, and any characters. Instead of saying "a cat in a garden", say "a fluffy gray cat sitting beside pink tulips in a sunny garden".
356
364
  - Set the Scene: Describe the environment or background. Mention if it's indoors or outdoors, the time of day, weather conditions, and any specific setting details like a beach, forest, cityscape, etc.
@@ -364,10 +372,9 @@ Keep it 100 words or less.
364
372
 
365
373
  The prompt to rewrite is:
366
374
  {Reference to image-prompt-field}
367
- "
375
+ ```
368
376
 
369
377
  The rules can be extracted into an AI Context document and reused in other instructions as needed. This approach can also be used to inform a reusable styleguide for image generation.
370
-
371
378
  ## Full document translation
372
379
  <img width="250" alt="Translate document action" src="https://github.com/sanity-io/assist/assets/835514/932968ee-1a8c-4389-8822-338188f88b40">
373
380
 
package/dist/index.esm.js CHANGED
@@ -137,6 +137,17 @@ function getCaptionFieldOption(schemaType) {
137
137
  }
138
138
  return getCaptionFieldOption(schemaType.type);
139
139
  }
140
+ function getImagePromptFieldOption(schemaType) {
141
+ var _a;
142
+ if (!schemaType) {
143
+ return void 0;
144
+ }
145
+ const imagePromptField = (_a = schemaType.options) == null ? void 0 : _a.imagePromptField;
146
+ if (imagePromptField) {
147
+ return imagePromptField;
148
+ }
149
+ return getImagePromptFieldOption(schemaType.type);
150
+ }
140
151
  function isSchemaAssistEnabled(type) {
141
152
  var _a, _b;
142
153
  return !((_b = (_a = type.options) == null ? void 0 : _a.aiWritingAssistance) == null ? void 0 : _b.exclude);
@@ -1047,6 +1058,48 @@ function useGenerateCaption(apiClient) {
1047
1058
  loading
1048
1059
  }), [generateCaption, loading]);
1049
1060
  }
1061
+ function useGenerateImage(apiClient) {
1062
+ const [loading, setLoading] = useState(false);
1063
+ const user = useCurrentUser();
1064
+ const schema = useSchema();
1065
+ const types = useMemo(() => serializeSchema(schema, {
1066
+ leanFormat: true
1067
+ }), [schema]);
1068
+ const toast = useToast();
1069
+ const generateImage = useCallback(_ref6 => {
1070
+ let {
1071
+ path,
1072
+ documentId
1073
+ } = _ref6;
1074
+ setLoading(true);
1075
+ return apiClient.request({
1076
+ method: "POST",
1077
+ url: "/assist/tasks/generate-image/".concat(apiClient.config().dataset, "?projectId=").concat(apiClient.config().projectId),
1078
+ body: {
1079
+ path,
1080
+ documentId,
1081
+ types,
1082
+ userId: user == null ? void 0 : user.id
1083
+ }
1084
+ }).catch(e => {
1085
+ toast.push({
1086
+ status: "error",
1087
+ title: "Generate image from prompt failed",
1088
+ description: e.message
1089
+ });
1090
+ setLoading(false);
1091
+ throw e;
1092
+ }).finally(() => {
1093
+ setTimeout(() => {
1094
+ setLoading(false);
1095
+ }, 2e3);
1096
+ });
1097
+ }, [setLoading, apiClient, toast, user, types]);
1098
+ return useMemo(() => ({
1099
+ generateImage,
1100
+ loading
1101
+ }), [generateImage, loading]);
1102
+ }
1050
1103
  function useGetInstructStatus(apiClient) {
1051
1104
  const [loading, setLoading] = useState(true);
1052
1105
  const getInstructStatus = useCallback(async () => {
@@ -1236,8 +1289,8 @@ function RunInstructionProvider(props) {
1236
1289
  runInstructionRequest({
1237
1290
  ...request,
1238
1291
  instructionKey: instruction._key,
1239
- userTexts: Object.entries(inputs).map(_ref6 => {
1240
- let [key, value] = _ref6;
1292
+ userTexts: Object.entries(inputs).map(_ref7 => {
1293
+ let [key, value] = _ref7;
1241
1294
  return {
1242
1295
  blockKey: key,
1243
1296
  userInput: value
@@ -1250,8 +1303,8 @@ function RunInstructionProvider(props) {
1250
1303
  const open = !!runRequest;
1251
1304
  const runDisabled = useMemo(() => {
1252
1305
  var _a2, _b;
1253
- return ((_b = (_a2 = runRequest == null ? void 0 : runRequest.userInputBlocks) == null ? void 0 : _a2.length) != null ? _b : 0) > Object.entries(inputs).filter(_ref7 => {
1254
- let [, value] = _ref7;
1306
+ return ((_b = (_a2 = runRequest == null ? void 0 : runRequest.userInputBlocks) == null ? void 0 : _a2.length) != null ? _b : 0) > Object.entries(inputs).filter(_ref8 => {
1307
+ let [, value] = _ref8;
1255
1308
  return !!value;
1256
1309
  }).length;
1257
1310
  }, [runRequest == null ? void 0 : runRequest.userInputBlocks, inputs]);
@@ -1643,13 +1696,13 @@ function useSelectedSchema(fieldPath, documentSchema) {
1643
1696
  return currentSchema;
1644
1697
  }, [documentSchema, fieldPath]);
1645
1698
  }
1646
- function FieldsInitializer(_ref8) {
1699
+ function FieldsInitializer(_ref9) {
1647
1700
  let {
1648
1701
  pathKey,
1649
1702
  activePath,
1650
1703
  fieldExists,
1651
1704
  onChange
1652
- } = _ref8;
1705
+ } = _ref9;
1653
1706
  const initialized = useRef(false);
1654
1707
  useEffect(() => {
1655
1708
  if (initialized.current || fieldExists || activePath || !pathKey) {
@@ -2177,10 +2230,10 @@ const assistInspector = {
2177
2230
  showAsAction: false
2178
2231
  }),
2179
2232
  component: AssistInspectorWrapper,
2180
- onClose(_ref9) {
2233
+ onClose(_ref10) {
2181
2234
  let {
2182
2235
  params
2183
- } = _ref9;
2236
+ } = _ref10;
2184
2237
  return {
2185
2238
  params: typed({
2186
2239
  ...params,
@@ -2253,11 +2306,11 @@ var __template$3 = (cooked, raw) => __freeze$3(__defProp$3(cooked, "raw", {
2253
2306
  var _a$3, _b$1;
2254
2307
  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"])));
2255
2308
  const FadeInDiv = styled.div(_b$1 || (_b$1 = __template$3(["\n animation-name: ", ";\n animation-timing-function: ease-in-out;\n"])), fadeIn);
2256
- const FadeInContent = forwardRef(function FadeInContent2(_ref10, ref) {
2309
+ const FadeInContent = forwardRef(function FadeInContent2(_ref11, ref) {
2257
2310
  let {
2258
2311
  children,
2259
2312
  durationMs = 250
2260
- } = _ref10;
2313
+ } = _ref11;
2261
2314
  return /* @__PURE__ */jsx(FadeInDiv, {
2262
2315
  ref,
2263
2316
  style: {
@@ -4547,6 +4600,20 @@ const getLanguageParams = (select, document) => {
4547
4600
  }
4548
4601
  return selectedValue;
4549
4602
  };
4603
+ const toFieldLanguagesKeyPrefix = "sanityStudio:assist:field-languages:from:";
4604
+ function getPreferredToFieldLanguages(fromLanguageId) {
4605
+ if (typeof localStorage === "undefined") {
4606
+ return [];
4607
+ }
4608
+ const value = localStorage.getItem("".concat(toFieldLanguagesKeyPrefix).concat(fromLanguageId));
4609
+ return value ? JSON.parse(value) : [];
4610
+ }
4611
+ function setPreferredToFieldLanguages(fromLanguageId, languageIds) {
4612
+ if (typeof localStorage === "undefined") {
4613
+ return;
4614
+ }
4615
+ localStorage.setItem("".concat(toFieldLanguagesKeyPrefix).concat(fromLanguageId), JSON.stringify(languageIds));
4616
+ }
4550
4617
  const FieldTranslationContext = createContext({
4551
4618
  openFieldTranslation: () => {},
4552
4619
  translationLoading: false
@@ -4591,26 +4658,29 @@ function FieldTranslationProvider(props) {
4591
4658
  setFieldLanguageMaps(void 0);
4592
4659
  return;
4593
4660
  }
4594
- const to = languages2.filter(l => l.id !== (from == null ? void 0 : from.id));
4595
- setToLanguages(to);
4661
+ const preferred = getPreferredToFieldLanguages(from.id);
4662
+ const allToLanguages = languages2.filter(l => l.id !== (from == null ? void 0 : from.id));
4663
+ const filteredToLanguages = allToLanguages.filter(l => !preferred.length || preferred.includes(l.id));
4664
+ setToLanguages(filteredToLanguages);
4596
4665
  const fromId = from == null ? void 0 : from.id;
4597
- const toIds = (_a2 = to == null ? void 0 : to.map(l => l.id)) != null ? _a2 : [];
4666
+ const allToIds = (_a2 = allToLanguages == null ? void 0 : allToLanguages.map(l => l.id)) != null ? _a2 : [];
4598
4667
  const docMembers = getDocumentMembersFlat(document, documentSchema);
4599
- if (fromId && (toIds == null ? void 0 : toIds.length)) {
4600
- const transMap = getFieldLanguageMap(documentSchema, docMembers, fromId, toIds, (_b2 = config == null ? void 0 : config.translationOutputs) != null ? _b2 : defaultLanguageOutputs);
4668
+ if (fromId && (allToIds == null ? void 0 : allToIds.length)) {
4669
+ const transMap = getFieldLanguageMap(documentSchema, docMembers, fromId, allToIds, (_b2 = config == null ? void 0 : config.translationOutputs) != null ? _b2 : defaultLanguageOutputs);
4601
4670
  setFieldLanguageMaps(transMap);
4602
4671
  } else {
4603
4672
  setFieldLanguageMaps(void 0);
4604
4673
  }
4605
4674
  }, [config]);
4606
4675
  const toggleToLanguage = useCallback((toggledLang, toLanguages2, languages2) => {
4607
- if (!languages2) {
4676
+ if (!languages2 || !fromLanguage) {
4608
4677
  return;
4609
4678
  }
4610
4679
  const wasSelected = !!(toLanguages2 == null ? void 0 : toLanguages2.find(l => l.id === toggledLang.id));
4611
4680
  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);
4612
4681
  setToLanguages(newToLangs);
4613
- }, []);
4682
+ setPreferredToFieldLanguages(fromLanguage.id, newToLangs.map(l => l.id));
4683
+ }, [fromLanguage]);
4614
4684
  const openFieldTranslation = useCallback(async params => {
4615
4685
  setDialogOpen(true);
4616
4686
  const languageParams = getLanguageParams(config == null ? void 0 : config.selectLanguageParams, params.document);
@@ -4727,8 +4797,7 @@ function FieldTranslationProvider(props) {
4727
4797
  name: "toLang",
4728
4798
  value: l.id,
4729
4799
  checked: !!(toLanguages == null ? void 0 : toLanguages.find(tl => tl.id === l.id)),
4730
- onClick: () => toggleToLanguage(l, toLanguages, languages),
4731
- disabled: !(fieldLanguageMaps == null ? void 0 : fieldLanguageMaps.find(tm => tm.outputs.find(o => o.id === l.id)))
4800
+ onClick: () => toggleToLanguage(l, toLanguages, languages)
4732
4801
  }), /* @__PURE__ */jsx(Text, {
4733
4802
  children: (_a2 = l.title) != null ? _a2 : l.id
4734
4803
  })]
@@ -4928,11 +4997,11 @@ function InstructionInput(props) {
4928
4997
  })]
4929
4998
  });
4930
4999
  }
4931
- function ObjectMember(_ref11) {
5000
+ function ObjectMember(_ref12) {
4932
5001
  let {
4933
5002
  fieldName,
4934
5003
  ...props
4935
- } = _ref11;
5004
+ } = _ref12;
4936
5005
  const member = findFieldMember(props.members, fieldName);
4937
5006
  return member ? /* @__PURE__ */jsx(ObjectInputMember, {
4938
5007
  ...props,
@@ -5071,8 +5140,8 @@ function IconInput(props) {
5071
5140
  onChange
5072
5141
  } = props;
5073
5142
  const id = useId();
5074
- const items = useMemo(() => Object.entries(icons).map(_ref12 => {
5075
- let [key, icon] = _ref12;
5143
+ const items = useMemo(() => Object.entries(icons).map(_ref13 => {
5144
+ let [key, icon] = _ref13;
5076
5145
  return /* @__PURE__ */jsx(IconItem, {
5077
5146
  iconKey: key,
5078
5147
  icon,
@@ -5100,12 +5169,12 @@ function IconInput(props) {
5100
5169
  }
5101
5170
  });
5102
5171
  }
5103
- function IconItem(_ref13) {
5172
+ function IconItem(_ref14) {
5104
5173
  let {
5105
5174
  icon,
5106
5175
  iconKey: key,
5107
5176
  onChange
5108
- } = _ref13;
5177
+ } = _ref14;
5109
5178
  const onClick = useCallback(() => onChange(set(key)), [onChange, key]);
5110
5179
  return /* @__PURE__ */jsx(MenuItem, {
5111
5180
  icon,
@@ -5116,8 +5185,8 @@ function IconItem(_ref13) {
5116
5185
  }
5117
5186
  function getIcon(iconName) {
5118
5187
  var _a, _b;
5119
- return (_b = (_a = Object.entries(icons).find(_ref14 => {
5120
- let [key] = _ref14;
5188
+ return (_b = (_a = Object.entries(icons).find(_ref15 => {
5189
+ let [key] = _ref15;
5121
5190
  return key === iconName;
5122
5191
  })) == null ? void 0 : _a[1]) != null ? _b : icons.sparkles;
5123
5192
  }
@@ -5276,11 +5345,11 @@ const contextDocumentSchema = defineType({
5276
5345
  title: "title",
5277
5346
  context: "context"
5278
5347
  },
5279
- prepare(_ref15) {
5348
+ prepare(_ref16) {
5280
5349
  let {
5281
5350
  title,
5282
5351
  context
5283
- } = _ref15;
5352
+ } = _ref16;
5284
5353
  var _a;
5285
5354
  const text = context == null ? void 0 : context.flatMap(block => block == null ? void 0 : block.children).flatMap(child => {
5286
5355
  var _a2;
@@ -5380,11 +5449,11 @@ function InstructionOutputField(props) {
5380
5449
  children: props.children
5381
5450
  });
5382
5451
  }
5383
- function EnabledOutputField(_ref16) {
5452
+ function EnabledOutputField(_ref17) {
5384
5453
  let {
5385
5454
  fieldSchema,
5386
5455
  ...props
5387
- } = _ref16;
5456
+ } = _ref17;
5388
5457
  var _a;
5389
5458
  const [open, setOpen] = useState(!!((_a = props.value) == null ? void 0 : _a.length));
5390
5459
  const onExpand = useCallback(() => setOpen(true), []);
@@ -5432,11 +5501,11 @@ function useEmptySelectAllValue(value, allowedValues, onChange) {
5432
5501
  }
5433
5502
  }, [allowedValues, value, onChange]);
5434
5503
  }
5435
- function ObjectOutputInput(_ref17) {
5504
+ function ObjectOutputInput(_ref18) {
5436
5505
  let {
5437
5506
  fieldSchema,
5438
5507
  ...props
5439
- } = _ref17;
5508
+ } = _ref18;
5440
5509
  const {
5441
5510
  value,
5442
5511
  onChange
@@ -5483,11 +5552,11 @@ function ObjectOutputInput(_ref17) {
5483
5552
  })
5484
5553
  });
5485
5554
  }
5486
- function ArrayOutputInput(_ref18) {
5555
+ function ArrayOutputInput(_ref19) {
5487
5556
  let {
5488
5557
  fieldSchema,
5489
5558
  ...props
5490
- } = _ref18;
5559
+ } = _ref19;
5491
5560
  const {
5492
5561
  value,
5493
5562
  onChange
@@ -5532,13 +5601,13 @@ function ArrayOutputInput(_ref18) {
5532
5601
  })
5533
5602
  });
5534
5603
  }
5535
- function Selectable(_ref19) {
5604
+ function Selectable(_ref20) {
5536
5605
  let {
5537
5606
  title,
5538
5607
  arrayValue,
5539
5608
  value,
5540
5609
  onChange
5541
- } = _ref19;
5610
+ } = _ref20;
5542
5611
  const checked = !(arrayValue == null ? void 0 : arrayValue.length) || !!(arrayValue == null ? void 0 : arrayValue.find(v => v._key === value));
5543
5612
  const handleChange = useCallback(() => onChange(checked, value), [onChange, checked, value]);
5544
5613
  return /* @__PURE__ */jsxs(Flex, {
@@ -5603,10 +5672,10 @@ const fieldReference = defineType({
5603
5672
  select: {
5604
5673
  path: "path"
5605
5674
  },
5606
- prepare(_ref20) {
5675
+ prepare(_ref21) {
5607
5676
  let {
5608
5677
  path
5609
- } = _ref20;
5678
+ } = _ref21;
5610
5679
  return {
5611
5680
  title: path,
5612
5681
  path,
@@ -5751,12 +5820,12 @@ const instruction = defineType({
5751
5820
  title: "title",
5752
5821
  userId: "userId"
5753
5822
  },
5754
- prepare: _ref21 => {
5823
+ prepare: _ref22 => {
5755
5824
  let {
5756
5825
  icon,
5757
5826
  title,
5758
5827
  userId
5759
- } = _ref21;
5828
+ } = _ref22;
5760
5829
  return {
5761
5830
  title,
5762
5831
  icon: icon ? icons[icon] : SparklesIcon,
@@ -6104,7 +6173,7 @@ function PrivateIcon() {
6104
6173
  children: /* @__PURE__ */jsx(LockIcon, {})
6105
6174
  });
6106
6175
  }
6107
- const ImageContext = createContext(void 0);
6176
+ const ImageContext = createContext({});
6108
6177
  function ImageContextProvider(props) {
6109
6178
  var _a;
6110
6179
  const {
@@ -6140,17 +6209,19 @@ function ImageContextProvider(props) {
6140
6209
  }, [schemaType, path, assetRef, assetRefState, documentId, generateCaption, isSyncing]);
6141
6210
  const context = useMemo(() => {
6142
6211
  const captionField = getCaptionFieldOption(schemaType);
6143
- return captionField ? {
6144
- captionPath: pathToString([...path, captionField]),
6212
+ const imagePromptField = getImagePromptFieldOption(schemaType);
6213
+ return {
6214
+ captionPath: captionField ? pathToString([...path, captionField]) : void 0,
6215
+ imagePromptPath: imagePromptField ? pathToString([...path, imagePromptField]) : void 0,
6145
6216
  assetRef
6146
- } : void 0;
6217
+ };
6147
6218
  }, [schemaType, path, assetRef]);
6148
6219
  return /* @__PURE__ */jsx(ImageContext.Provider, {
6149
6220
  value: context,
6150
6221
  children: props.renderDefault(props)
6151
6222
  });
6152
6223
  }
6153
- function node$2(node2) {
6224
+ function node$3(node2) {
6154
6225
  return node2;
6155
6226
  }
6156
6227
  const generateCaptionsActions = {
@@ -6171,7 +6242,7 @@ const generateCaptionsActions = {
6171
6242
  documentId
6172
6243
  } = useAssistDocumentContext();
6173
6244
  return useMemo(() => {
6174
- return node$2({
6245
+ return node$3({
6175
6246
  type: "action",
6176
6247
  icon: loading ? () => /* @__PURE__ */jsx(Box, {
6177
6248
  style: {
@@ -6202,7 +6273,7 @@ const generateCaptionsActions = {
6202
6273
  return void 0;
6203
6274
  }
6204
6275
  };
6205
- function node$1(node2) {
6276
+ function node$2(node2) {
6206
6277
  return node2;
6207
6278
  }
6208
6279
  const translateActions = {
@@ -6249,7 +6320,7 @@ const translateActions = {
6249
6320
  value: languageId
6250
6321
  } = (_a2 = extractWithPath(languagePath, documentValue)[0]) != null ? _a2 : {};
6251
6322
  const title = path.length ? "Translate" : "Translate document";
6252
- return node$1({
6323
+ return node$2({
6253
6324
  type: "action",
6254
6325
  icon: translationApi.loading ? () => /* @__PURE__ */jsx(Box, {
6255
6326
  style: {
@@ -6284,7 +6355,7 @@ const translateActions = {
6284
6355
  isDocAssistable: documentIsAssistable != null ? documentIsAssistable : false,
6285
6356
  task: fieldTranslate.openFieldTranslation
6286
6357
  });
6287
- const translateFieldsAction = useMemo(() => fieldTransEnabled ? node$1({
6358
+ const translateFieldsAction = useMemo(() => fieldTransEnabled ? node$2({
6288
6359
  type: "action",
6289
6360
  icon: fieldTranslate.translationLoading ? () => /* @__PURE__ */jsx(Box, {
6290
6361
  style: {
@@ -6311,7 +6382,7 @@ const translateActions = {
6311
6382
  disabled: fieldTranslate.translationLoading
6312
6383
  }) : void 0, [openFieldTranslation, documentSchemaType, documentId, fieldTranslate.translationLoading, fieldTransEnabled, path]);
6313
6384
  return useMemo(() => {
6314
- return node$1({
6385
+ return node$2({
6315
6386
  type: "group",
6316
6387
  icon: () => null,
6317
6388
  title: "Translation",
@@ -6323,6 +6394,57 @@ const translateActions = {
6323
6394
  return void 0;
6324
6395
  }
6325
6396
  };
6397
+ function node$1(node2) {
6398
+ return node2;
6399
+ }
6400
+ const generateImagActions = {
6401
+ name: "sanity-assist-generate-image",
6402
+ useAction(props) {
6403
+ const pathKey = usePathKey(props.path);
6404
+ const {
6405
+ config
6406
+ } = useAiAssistanceConfig();
6407
+ const apiClient = useApiClient(config == null ? void 0 : config.__customApiClient);
6408
+ const {
6409
+ generateImage,
6410
+ loading
6411
+ } = useGenerateImage(apiClient);
6412
+ const imageContext = useContext(ImageContext);
6413
+ if (imageContext && pathKey === (imageContext == null ? void 0 : imageContext.imagePromptPath)) {
6414
+ const {
6415
+ documentId
6416
+ } = useAssistDocumentContext();
6417
+ return useMemo(() => {
6418
+ return node$1({
6419
+ type: "action",
6420
+ icon: loading ? () => /* @__PURE__ */jsx(Box, {
6421
+ style: {
6422
+ height: 17
6423
+ },
6424
+ children: /* @__PURE__ */jsx(Spinner, {
6425
+ style: {
6426
+ transform: "translateY(6px)"
6427
+ }
6428
+ })
6429
+ }) : ImageIcon,
6430
+ title: "Generate image from prompt",
6431
+ onAction: () => {
6432
+ if (loading) {
6433
+ return;
6434
+ }
6435
+ generateImage({
6436
+ path: pathKey,
6437
+ documentId: documentId != null ? documentId : ""
6438
+ });
6439
+ },
6440
+ renderAsButton: true,
6441
+ disabled: loading
6442
+ });
6443
+ }, [generateImage, pathKey, documentId, loading]);
6444
+ }
6445
+ return void 0;
6446
+ }
6447
+ };
6326
6448
  function node(node2) {
6327
6449
  return node2;
6328
6450
  }
@@ -6379,6 +6501,7 @@ const assistFieldActions = {
6379
6501
  const isPathSelected = pathKey === selectedPath;
6380
6502
  const isSelected = isInspectorOpen && isPathSelected;
6381
6503
  const imageCaptionAction = generateCaptionsActions.useAction(props);
6504
+ const imageGenAction = generateImagActions.useAction(props);
6382
6505
  const translateAction = translateActions.useAction(typed({
6383
6506
  ...props,
6384
6507
  documentId: assistableDocumentId,
@@ -6411,7 +6534,7 @@ const assistFieldActions = {
6411
6534
  }, [fieldAssist == null ? void 0 : fieldAssist.instructions]);
6412
6535
  const instructions = useMemo(() => [...privateInstructions, ...sharedInstructions], [privateInstructions, sharedInstructions]);
6413
6536
  const runInstructionsGroup = useMemo(() => {
6414
- return (instructions == null ? void 0 : instructions.length) || imageCaptionAction || translateAction ? node({
6537
+ return (instructions == null ? void 0 : instructions.length) || imageCaptionAction || translateAction || imageGenAction ? node({
6415
6538
  type: "group",
6416
6539
  icon: () => null,
6417
6540
  title: "Run instructions",
@@ -6422,10 +6545,10 @@ const assistFieldActions = {
6422
6545
  hidden: isHidden,
6423
6546
  documentIsNew: !!documentIsNew,
6424
6547
  assistSupported
6425
- }))), imageCaptionAction].filter(a => !!a),
6548
+ }))), imageCaptionAction, imageGenAction].filter(a => !!a),
6426
6549
  expanded: true
6427
6550
  }) : void 0;
6428
- }, [instructions, currentUser == null ? void 0 : currentUser.id, onInstructionAction, isHidden, documentIsNew, assistSupported, imageCaptionAction, translateAction]);
6551
+ }, [instructions, currentUser == null ? void 0 : currentUser.id, onInstructionAction, isHidden, documentIsNew, assistSupported, imageCaptionAction, translateAction, imageGenAction]);
6429
6552
  const instructionsLength = (instructions == null ? void 0 : instructions.length) || 0;
6430
6553
  const manageInstructionsItem = useMemo(() => node({
6431
6554
  type: "action",
@@ -6441,10 +6564,10 @@ const assistFieldActions = {
6441
6564
  children: [runInstructionsGroup, translateAction, assistSupported && manageInstructionsItem].filter(c => !!c).filter(c => c.type === "group" ? c.children.length : true),
6442
6565
  expanded: false,
6443
6566
  renderAsButton: true,
6444
- hidden: !assistSupported && !imageCaptionAction && !translateAction
6567
+ hidden: !assistSupported && !imageCaptionAction && !translateAction && !imageGenAction
6445
6568
  }), [
6446
6569
  //documentIsNew,
6447
- runInstructionsGroup, manageInstructionsItem, assistSupported, imageCaptionAction, translateAction]);
6570
+ runInstructionsGroup, manageInstructionsItem, assistSupported, imageCaptionAction, translateAction, imageGenAction]);
6448
6571
  const emptyAction = useMemo(() => node({
6449
6572
  type: "action",
6450
6573
  hidden: !assistSupported,
@@ -6454,7 +6577,7 @@ const assistFieldActions = {
6454
6577
  title: pluginTitleShort,
6455
6578
  selected: isSelected
6456
6579
  }), [assistSupported, manageInstructions, isSelected]);
6457
- if (instructionsLength === 0 && !imageCaptionAction && !translateAction) {
6580
+ if (instructionsLength === 0 && !imageCaptionAction && !translateAction && !imageGenAction) {
6458
6581
  return emptyAction;
6459
6582
  }
6460
6583
  return group;
@@ -6567,11 +6690,11 @@ function AssistDocumentInputWrapper(props) {
6567
6690
  documentId
6568
6691
  });
6569
6692
  }
6570
- function AssistDocumentInput(_ref22) {
6693
+ function AssistDocumentInput(_ref23) {
6571
6694
  let {
6572
6695
  documentId,
6573
6696
  ...props
6574
- } = _ref22;
6697
+ } = _ref23;
6575
6698
  useInstructionToaster(documentId, props.schemaType);
6576
6699
  const schemaType = useMemo(() => {
6577
6700
  if (props.schemaType.name !== assistDocumentTypeName) {
@@ -6677,11 +6800,11 @@ const assist = definePlugin(config => {
6677
6800
  }
6678
6801
  return prev;
6679
6802
  },
6680
- unstable_fieldActions: (prev, _ref23) => {
6803
+ unstable_fieldActions: (prev, _ref24) => {
6681
6804
  let {
6682
6805
  documentType,
6683
6806
  schema
6684
- } = _ref23;
6807
+ } = _ref24;
6685
6808
  if (documentType === assistDocumentTypeName) {
6686
6809
  return [];
6687
6810
  }
@@ -6691,12 +6814,12 @@ const assist = definePlugin(config => {
6691
6814
  }
6692
6815
  return prev;
6693
6816
  },
6694
- unstable_languageFilter: (prev, _ref24) => {
6817
+ unstable_languageFilter: (prev, _ref25) => {
6695
6818
  let {
6696
6819
  documentId,
6697
6820
  schema,
6698
6821
  schemaType
6699
- } = _ref24;
6822
+ } = _ref25;
6700
6823
  if (schemaType === assistDocumentTypeName) {
6701
6824
  return [];
6702
6825
  }