@sanity/assist 4.4.6 → 4.4.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -1,10 +1,10 @@
1
1
  import { jsx, jsxs, Fragment } from "react/jsx-runtime";
2
- import { pathToString, getVersionFromId, getPublishedId, isVersionId, useEditState, useCurrentUser, useClient, typed, isObjectSchemaType, stringToPath, isKeySegment, isArraySchemaType, useSchema, FormFieldHeaderText, PatchEvent, unset, getVersionId, getDraftId, useColorSchemeValue, useFormCallbacks, useDocumentStore, useDocumentPresence, createPatchChannel, FormBuilder, fromMutationPatches, StatusButton, PresenceOverlay, VirtualizerScrollInstanceProvider, isDocumentSchemaType, useSyncState, set, useWorkspaceSchemaId, MemberFieldError, FormCallbacksProvider, FormInput, setIfMissing, insert, ObjectInputMember, isArrayOfObjectsSchemaType, defineType, defineField, defineArrayMember, definePlugin } from "sanity";
2
+ import { pathToString, getVersionFromId, getPublishedId, isVersionId, useEditState, useCurrentUser, useClient, typed, FormFieldHeaderText, PatchEvent, unset, isObjectSchemaType, stringToPath, isKeySegment, useSchema, getVersionId, getDraftId, useColorSchemeValue, isArraySchemaType, useFormCallbacks, useDocumentStore, useDocumentPresence, createPatchChannel, FormBuilder, fromMutationPatches, StatusButton, PresenceOverlay, VirtualizerScrollInstanceProvider, isDocumentSchemaType, useSyncState, set, useWorkspaceSchemaId, MemberFieldError, FormCallbacksProvider, FormInput, setIfMissing, insert, ObjectInputMember, isArrayOfObjectsSchemaType, defineType, defineField, defineArrayMember, definePlugin } from "sanity";
3
3
  import { useToast, useLayer, Dialog, Stack, Flex, Tooltip, Text, TextArea, Button, Badge, Popover, Card, Box, ErrorBoundary, focusFirstDescendant, Spinner, Container, Autocomplete, Breadcrumbs, useClickOutside, useGlobalKeyDown, useTheme, rgba, Radio, Checkbox, ThemeProvider, MenuButton, Menu, MenuItem, Switch, Label } from "@sanity/ui";
4
4
  import { useRef, useState, useEffect, useMemo, createContext, useContext, useCallback, useId, forwardRef, createElement, useReducer } from "react";
5
5
  import { useDocumentPane, usePaneRouter, DocumentInspectorHeader, DocumentPaneProvider } from "sanity/structure";
6
6
  import { minutesToMilliseconds, isAfter, addSeconds, formatDistanceToNow } from "date-fns";
7
- import { DocumentIcon, LinkIcon, ImageIcon, BlockContentIcon, OlistIcon, BlockquoteIcon, StringIcon, PlayIcon, SparklesIcon, ArrowRightIcon, CheckmarkIcon, SearchIcon, SyncIcon, ErrorOutlineIcon, CheckmarkCircleIcon, ClockIcon, CloseCircleIcon, RetryIcon, CloseIcon, icons, TranslateIcon, LockIcon, ControlsIcon, ArrowLeftIcon, TokenIcon, DocumentTextIcon, ThListIcon, CodeIcon, ComposeIcon } from "@sanity/icons";
7
+ import { PlayIcon, DocumentIcon, LinkIcon, ImageIcon, BlockContentIcon, OlistIcon, BlockquoteIcon, StringIcon, SparklesIcon, ArrowRightIcon, CheckmarkIcon, SearchIcon, SyncIcon, ErrorOutlineIcon, CheckmarkCircleIcon, ClockIcon, CloseCircleIcon, RetryIcon, CloseIcon, icons, TranslateIcon, LockIcon, ControlsIcon, ArrowLeftIcon, TokenIcon, DocumentTextIcon, ThListIcon, CodeIcon, ComposeIcon } from "@sanity/icons";
8
8
  import { extractWithPath } from "@sanity/mutator";
9
9
  import { keyframes, styled } from "styled-components";
10
10
  import { tap, mergeMap, share, take, filter, distinctUntilChanged, catchError } from "rxjs/operators";
@@ -392,221 +392,6 @@ function useAssistDocumentContext() {
392
392
  throw new Error("AssistDocumentContext value is missing");
393
393
  return context;
394
394
  }
395
- const SelectedFieldContext = createContext(void 0), SelectedFieldContextProvider = SelectedFieldContext.Provider, maxDepth = 6;
396
- function getTypeIcon(schemaType) {
397
- let t = schemaType;
398
- for (; t; ) {
399
- if (t.icon) return t.icon;
400
- t = t.type;
401
- }
402
- return isType(schemaType, "slug") ? LinkIcon : isType(schemaType, "image") ? ImageIcon : schemaType.jsonType === "array" && isPortableTextArray(schemaType) ? BlockContentIcon : schemaType.jsonType === "array" ? OlistIcon : schemaType.jsonType === "object" ? BlockquoteIcon : schemaType.jsonType === "string" ? StringIcon : DocumentIcon;
403
- }
404
- function asFieldRefsByTypePath(fieldRefs) {
405
- return fieldRefs.reduce(
406
- (acc, ref) => ({ ...acc, [ref.key]: ref }),
407
- {}
408
- );
409
- }
410
- function getFieldRefsWithDocument(schemaType) {
411
- const fields = getFieldRefs(schemaType);
412
- return [
413
- {
414
- key: documentRootKey,
415
- icon: schemaType.icon ?? DocumentIcon,
416
- title: "The entire document",
417
- path: [],
418
- schemaType
419
- },
420
- ...fields
421
- ];
422
- }
423
- function getFieldRefs(schemaType, parent, depth = 0) {
424
- return depth >= maxDepth ? [] : schemaType.fields.filter((f) => !f.name.startsWith("_")).flatMap((field) => {
425
- const path = parent ? [...parent.path, field.name] : [field.name], title = field.type.title ?? field.name, fieldRef = {
426
- key: patchableKey(pathToString(path)),
427
- path,
428
- title: parent ? [parent.title, title].join(" / ") : title,
429
- schemaType: field.type,
430
- icon: getTypeIcon(field.type)
431
- }, fields = field.type.jsonType === "object" ? getFieldRefs(field.type, fieldRef, depth + 1) : [], syntheticFields = field.type.jsonType === "array" ? getSyntheticFields(field.type, fieldRef, depth + 1) : [];
432
- return isAssistSupported(field.type) ? [fieldRef, ...fields, ...syntheticFields] : [...fields, ...syntheticFields];
433
- });
434
- }
435
- function getSyntheticFields(schemaType, parent, depth = 0) {
436
- return depth >= maxDepth ? [] : schemaType.of.filter((itemType) => !isType(itemType, "block")).flatMap((itemType) => {
437
- const segment = { _key: itemType.name }, title = itemType.title ?? itemType.name, path = parent ? [...parent.path, segment] : [segment], fieldRef = {
438
- key: patchableKey(pathToString(path)),
439
- path,
440
- title: parent ? [parent.title, title].join(" / ") : title,
441
- schemaType: itemType,
442
- icon: getTypeIcon(itemType),
443
- synthetic: !0
444
- }, fields = itemType.jsonType === "object" ? getFieldRefs(itemType, fieldRef, depth + 1) : [];
445
- return isAssistSupported(itemType) ? [fieldRef, ...fields] : fields;
446
- });
447
- }
448
- function getTypePath(doc, pathString) {
449
- if (!pathString)
450
- return;
451
- const path = stringToPath(pathString), currentPath = [];
452
- let valid = !0;
453
- const syntheticPath = path.map((segment) => {
454
- if (currentPath.push(segment), isKeySegment(segment)) {
455
- const match = extractWithPath(pathToString(currentPath), doc)[0], value = match?.value;
456
- if (match && value && typeof value == "object" && "_type" in value)
457
- return { _key: value._type };
458
- valid = !1;
459
- }
460
- return segment;
461
- });
462
- return valid ? patchableKey(pathToString(syntheticPath)) : void 0;
463
- }
464
- function patchableKey(pathKey) {
465
- return pathKey.replace(/[=]=/g, ":").replace(/[[\]]/g, "|").replace(/"/g, "");
466
- }
467
- function useTypePath(doc, pathString) {
468
- return useMemo(() => getTypePath(doc, pathString), [doc, pathString]);
469
- }
470
- function useSelectedField(documentSchemaType, path) {
471
- const selectableFields = useMemo(
472
- () => documentSchemaType && isObjectSchemaType(documentSchemaType) ? getFieldRefsWithDocument(documentSchemaType) : [],
473
- [documentSchemaType]
474
- );
475
- return useMemo(() => path ? selectableFields?.find((f) => f.key === path) : void 0, [selectableFields, path]);
476
- }
477
- function getFieldTitle(field) {
478
- const schemaType = field?.schemaType;
479
- return field?.title ?? schemaType?.title ?? schemaType?.name ?? "Untitled";
480
- }
481
- function useAiPaneRouter() {
482
- const paneRouter = usePaneRouter();
483
- return useMemo(
484
- () => ({ ...paneRouter, params: paneRouter.params ?? {} }),
485
- [paneRouter]
486
- );
487
- }
488
- const hiddenTypes = [
489
- "any",
490
- "array",
491
- "block",
492
- "boolean",
493
- "crossDatasetReference",
494
- "date",
495
- "datetime",
496
- "document",
497
- "email",
498
- "file",
499
- "globalDocumentReference",
500
- "image",
501
- "number",
502
- "object",
503
- "reference",
504
- "span",
505
- "string",
506
- "text",
507
- "url",
508
- "slug",
509
- "geopoint",
510
- "sanity.assetSourceData",
511
- "sanity.imageAsset",
512
- "sanity.fileAsset",
513
- "sanity.imageCrop",
514
- "sanity.imageHotspot",
515
- "sanity.imageMetadata",
516
- "sanity.imageDimensions",
517
- "sanity.imagePalette",
518
- "sanity.imagePaletteSwatch",
519
- assistSerializedTypeName,
520
- assistSerializedFieldTypeName,
521
- "sanity-agent.job.document"
522
- ], inlineTypes = ["document", "object", "image", "file"];
523
- function serializeSchema(schema, options2) {
524
- 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, options2)).filter((t) => !("to" in t && t.to && !t.to.length || "of" in t && t.of && !t.of.length || "fields" in t && t.fields && !t.fields.length));
525
- return list.sort((a, b) => (a?.name ?? "").localeCompare(b?.name ?? "")), list;
526
- }
527
- function getSchemaStub(schemaType, schema, options2) {
528
- if (!schemaType.type?.name)
529
- throw console.error("Missing type name", schemaType.type), new Error("Type is missing name!");
530
- const baseSchema = {
531
- // we dont need type or id when we send using POST, so leave these out to save bandwidth
532
- ...options2?.leanFormat ? {} : { _id: `${assistSchemaIdPrefix}${schemaType.name}`, _type: assistSerializedTypeName },
533
- name: schemaType.name,
534
- title: schemaType.title,
535
- type: schemaType.type.name,
536
- ...getBaseFields(schema, schemaType, schemaType.type.name, options2)
537
- };
538
- return removeUndef(baseSchema);
539
- }
540
- function getBaseFields(schema, type, typeName, options2) {
541
- const schemaOptions = removeUndef({
542
- imagePromptField: type.options?.aiAssist?.imageInstructionField,
543
- embeddingsIndex: type.options?.aiAssist?.embeddingsIndex
544
- });
545
- return removeUndef({
546
- options: Object.keys(schemaOptions).length ? schemaOptions : void 0,
547
- values: Array.isArray(type?.options?.list) ? type?.options?.list.map(
548
- (v) => typeof v == "string" ? v : v.value ?? `${v.title}`
549
- ) : void 0,
550
- of: "of" in type && typeName === "array" ? arrayOf(type, schema, options2) : void 0,
551
- to: "to" in type && typeName === "reference" ? refToTypeNames(type) : void 0,
552
- fields: "fields" in type && inlineTypes.includes(typeName) ? serializeFields(schema, type, options2) : void 0,
553
- annotations: typeName === "block" && "fields" in type ? serializeAnnotations(type, schema, options2) : void 0,
554
- inlineOf: typeName === "block" && "fields" in type ? serializeInlineOf(type, schema, options2) : void 0,
555
- hidden: typeof type.hidden == "function" ? "function" : type.hidden ? !0 : void 0,
556
- readOnly: typeof type.readOnly == "function" ? "function" : type.readOnly ? !0 : void 0
557
- });
558
- }
559
- function serializeFields(schema, schemaType, options2) {
560
- return (schemaType.fieldsets ? schemaType.fieldsets.flatMap(
561
- (fs) => fs.single ? fs.field : fs.fields.map((f) => ({
562
- ...f,
563
- type: {
564
- ...f.type,
565
- // if fieldset is (conditionally) hidden, the field must be considered the same way
566
- // ie, if the field does not show up in conditionalMembers, it is hidden
567
- // regardless of weather or not it is the field function or the fieldset function that hides it
568
- hidden: typeof fs.hidden == "function" ? fs.hidden : fs.hidden ? !0 : f.type.hidden
569
- }
570
- }))
571
- ) : schemaType.fields).filter((f) => !["sanity.imageHotspot", "sanity.imageCrop"].includes(f.type?.name ?? "")).filter((f) => isAssistSupported(f.type)).map((field) => serializeMember(schema, field.type, field.name, options2));
572
- }
573
- function serializeMember(schema, type, name, options2) {
574
- const typeName = schema.get(type?.name) ? type.name : type.type?.name ?? "";
575
- return removeUndef({
576
- ...options2?.leanFormat ? {} : { _type: assistSerializedFieldTypeName },
577
- name,
578
- type: typeName,
579
- title: type.title,
580
- ...getBaseFields(schema, type, typeName, options2)
581
- });
582
- }
583
- function serializeInlineOf(blockSchemaType, schema, options2) {
584
- const childrenType = blockSchemaType.fields.find((f) => f.name === "children")?.type;
585
- if (!(!childrenType || !isArraySchemaType(childrenType)))
586
- return arrayOf(
587
- {
588
- of: childrenType.of.filter((t) => !isType(t, "span"))
589
- },
590
- schema,
591
- options2
592
- );
593
- }
594
- function serializeAnnotations(blockSchemaType, schema, options2) {
595
- const marksType = blockSchemaType.fields.find((f) => f.name === "markDefs")?.type;
596
- if (!(!marksType || !isArraySchemaType(marksType)))
597
- return arrayOf(marksType, schema, options2);
598
- }
599
- function arrayOf(arrayType, schema, options2) {
600
- return arrayType.of.filter((type) => isAssistSupported(type)).map((t) => serializeMember(schema, t, t.name, options2));
601
- }
602
- function refToTypeNames(type) {
603
- return type.to.map((t) => ({
604
- type: typed(t.name)
605
- }));
606
- }
607
- function removeUndef(obj) {
608
- return Object.keys(obj).forEach((key) => obj[key] === void 0 ? delete obj[key] : {}), obj;
609
- }
610
395
  const AiAssistanceConfigContext = createContext({});
611
396
  function useAiAssistanceConfig() {
612
397
  const context = useContext(AiAssistanceConfigContext);
@@ -617,33 +402,6 @@ function useAiAssistanceConfig() {
617
402
  function useSerializedTypes() {
618
403
  return useAiAssistanceConfig().serializedTypes;
619
404
  }
620
- function AiAssistanceConfigProvider(props) {
621
- const [status, setStatus] = useState(), [error, setError] = useState(), apiClient = useApiClient(props.config?.__customApiClient), { getInstructStatus, loading: statusLoading } = useGetInstructStatus(apiClient), { initInstruct, loading: initLoading } = useInitInstruct(apiClient), schema = useSchema(), serializedTypes = useMemo(() => serializeSchema(schema, { leanFormat: !0 }), [schema]);
622
- useEffect(() => {
623
- getInstructStatus().then((s) => setStatus(s)).catch((e) => {
624
- console.error(e), setError(e);
625
- });
626
- }, [getInstructStatus]);
627
- const init = useCallback(async () => {
628
- setError(void 0);
629
- try {
630
- await initInstruct();
631
- const status2 = await getInstructStatus();
632
- setStatus(status2);
633
- } catch (e) {
634
- console.error("Failed to init ai assistance", e), setError(e);
635
- }
636
- }, [initInstruct, getInstructStatus, setStatus]), { config, children } = props, context = useMemo(() => ({
637
- config,
638
- status,
639
- statusLoading,
640
- init,
641
- initLoading,
642
- error,
643
- serializedTypes
644
- }), [config, status, init, statusLoading, initLoading, error, serializedTypes]);
645
- return /* @__PURE__ */ jsx(AiAssistanceConfigContext.Provider, { value: context, children });
646
- }
647
405
  const basePath = "/assist/tasks/instruction", API_VERSION_WITH_EXTENDED_TYPES = "2025-04-01";
648
406
  function canUseAssist(status) {
649
407
  return status?.enabled && status.initialized && status.validToken;
@@ -1022,19 +780,105 @@ function useDraftDelayedTask(args) {
1022
780
  [setQueuedArgs, documentOnChange]
1023
781
  );
1024
782
  }
783
+ const maxDepth = 6;
784
+ function getTypeIcon(schemaType) {
785
+ let t = schemaType;
786
+ for (; t; ) {
787
+ if (t.icon) return t.icon;
788
+ t = t.type;
789
+ }
790
+ return isType(schemaType, "slug") ? LinkIcon : isType(schemaType, "image") ? ImageIcon : schemaType.jsonType === "array" && isPortableTextArray(schemaType) ? BlockContentIcon : schemaType.jsonType === "array" ? OlistIcon : schemaType.jsonType === "object" ? BlockquoteIcon : schemaType.jsonType === "string" ? StringIcon : DocumentIcon;
791
+ }
792
+ function asFieldRefsByTypePath(fieldRefs) {
793
+ return fieldRefs.reduce(
794
+ (acc, ref) => ({ ...acc, [ref.key]: ref }),
795
+ {}
796
+ );
797
+ }
798
+ function getDocumentFieldRef(schemaType) {
799
+ return {
800
+ key: documentRootKey,
801
+ icon: schemaType.icon ?? DocumentIcon,
802
+ title: "The entire document",
803
+ path: [],
804
+ schemaType
805
+ };
806
+ }
807
+ function getFieldRefs(schemaType, parent, depth = 0) {
808
+ return depth >= maxDepth ? [] : schemaType.fields.filter((f) => !f.name.startsWith("_")).flatMap((field) => {
809
+ const path = parent ? [...parent.path, field.name] : [field.name], title = field.type.title ?? field.name, fieldRef = {
810
+ key: patchableKey(pathToString(path)),
811
+ path,
812
+ title: parent ? [parent.title, title].join(" / ") : title,
813
+ schemaType: field.type,
814
+ icon: getTypeIcon(field.type)
815
+ }, fields = field.type.jsonType === "object" ? getFieldRefs(field.type, fieldRef, depth + 1) : [], syntheticFields = field.type.jsonType === "array" ? getSyntheticFields(field.type, fieldRef, depth + 1) : [];
816
+ return isAssistSupported(field.type) ? [fieldRef, ...fields, ...syntheticFields] : [...fields, ...syntheticFields];
817
+ });
818
+ }
819
+ function getSyntheticFields(schemaType, parent, depth = 0) {
820
+ return depth >= maxDepth ? [] : schemaType.of.filter((itemType) => !isType(itemType, "block")).flatMap((itemType) => {
821
+ const segment = { _key: itemType.name }, title = itemType.title ?? itemType.name, path = parent ? [...parent.path, segment] : [segment], fieldRef = {
822
+ key: patchableKey(pathToString(path)),
823
+ path,
824
+ title: parent ? [parent.title, title].join(" / ") : title,
825
+ schemaType: itemType,
826
+ icon: getTypeIcon(itemType),
827
+ synthetic: !0
828
+ }, fields = itemType.jsonType === "object" ? getFieldRefs(itemType, fieldRef, depth + 1) : [];
829
+ return isAssistSupported(itemType) ? [fieldRef, ...fields] : fields;
830
+ });
831
+ }
832
+ function getTypePath(doc, pathString) {
833
+ if (!pathString)
834
+ return;
835
+ const path = stringToPath(pathString), currentPath = [];
836
+ let valid = !0;
837
+ const syntheticPath = path.map((segment) => {
838
+ if (currentPath.push(segment), isKeySegment(segment)) {
839
+ const match = extractWithPath(pathToString(currentPath), doc)[0], value = match?.value;
840
+ if (match && value && typeof value == "object" && "_type" in value)
841
+ return { _key: value._type };
842
+ valid = !1;
843
+ }
844
+ return segment;
845
+ });
846
+ return valid ? patchableKey(pathToString(syntheticPath)) : void 0;
847
+ }
848
+ function patchableKey(pathKey) {
849
+ return pathKey.replace(/[=]=/g, ":").replace(/[[\]]/g, "|").replace(/"/g, "");
850
+ }
851
+ function useTypePath(doc, pathString) {
852
+ return useMemo(() => getTypePath(doc, pathString), [doc, pathString]);
853
+ }
854
+ function useSelectedField(documentSchemaType, path) {
855
+ const { getFieldRefs: getFieldRefs2 } = useAiAssistanceConfig(), selectableFields = useMemo(
856
+ () => documentSchemaType && isObjectSchemaType(documentSchemaType) ? [getDocumentFieldRef(documentSchemaType), ...getFieldRefs2(documentSchemaType.name)] : [],
857
+ [documentSchemaType, getFieldRefs2]
858
+ );
859
+ return useMemo(() => path ? selectableFields?.find((f) => f.key === path) : void 0, [selectableFields, path]);
860
+ }
861
+ function getFieldTitle(field) {
862
+ const schemaType = field?.schemaType;
863
+ return field?.title ?? schemaType?.title ?? schemaType?.name ?? "Untitled";
864
+ }
865
+ function useAiPaneRouter() {
866
+ const paneRouter = usePaneRouter();
867
+ return useMemo(
868
+ () => ({ ...paneRouter, params: paneRouter.params ?? {} }),
869
+ [paneRouter]
870
+ );
871
+ }
1025
872
  function useAssistDocumentContextValue(documentId, documentType) {
1026
- const schema = useSchema(), documentSchemaType = useMemo(() => {
873
+ const schema = useSchema(), { getFieldRefs: getFieldRefs2, getFieldRefsByTypePath } = useAiAssistanceConfig(), documentSchemaType = useMemo(() => {
1027
874
  const schemaType = schema.get(documentType);
1028
875
  if (!schemaType)
1029
876
  throw new Error(`Schema type "${documentType}" not found`);
1030
877
  return schemaType;
1031
- }, [documentType, schema]), { fieldRefs, fieldRefsByTypePath } = useMemo(() => {
1032
- const fieldRefs2 = getFieldRefs(documentSchemaType), fieldRefsByTypePath2 = asFieldRefsByTypePath(fieldRefs2);
1033
- return {
1034
- fieldRefs: fieldRefs2,
1035
- fieldRefsByTypePath: fieldRefsByTypePath2
1036
- };
1037
- }, [documentSchemaType]), {
878
+ }, [documentType, schema]), { fieldRefs, fieldRefsByTypePath } = useMemo(() => ({
879
+ fieldRefs: getFieldRefs2(documentType),
880
+ fieldRefsByTypePath: getFieldRefsByTypePath(documentType)
881
+ }), [getFieldRefs2, getFieldRefsByTypePath, documentType]), {
1038
882
  openInspector,
1039
883
  closeInspector,
1040
884
  inspector,
@@ -1601,7 +1445,10 @@ function InspectorOnboarding(props) {
1601
1445
  ] }) }) });
1602
1446
  }
1603
1447
  function FieldAutocomplete(props) {
1604
- const { id, schemaType, fieldPath, onSelect, includeDocument, filter: filter2 } = props, fieldRefs = useMemo(() => includeDocument ? getFieldRefsWithDocument(schemaType) : getFieldRefs(schemaType), [schemaType, includeDocument]), currentField = useMemo(
1448
+ const { id, schemaType, fieldPath, onSelect, includeDocument, filter: filter2 } = props, { getFieldRefs: getFieldRefs2 } = useAiAssistanceConfig(), fieldRefs = useMemo(() => {
1449
+ const refs = getFieldRefs2(schemaType.name);
1450
+ return includeDocument ? [getDocumentFieldRef(schemaType), ...refs] : refs;
1451
+ }, [schemaType, includeDocument, getFieldRefs2]), currentField = useMemo(
1605
1452
  () => fieldRefs.find((f) => f.key === fieldPath),
1606
1453
  [fieldPath, fieldRefs]
1607
1454
  ), autocompleteOptions = useMemo(
@@ -2602,6 +2449,195 @@ function FromLanguageRadio(props) {
2602
2449
  /* @__PURE__ */ jsx(Text, { children: radioLanguage.title ?? radioLanguage.id })
2603
2450
  ] }, langId);
2604
2451
  }
2452
+ const hiddenTypes = [
2453
+ "any",
2454
+ "array",
2455
+ "block",
2456
+ "boolean",
2457
+ "crossDatasetReference",
2458
+ "date",
2459
+ "datetime",
2460
+ "document",
2461
+ "email",
2462
+ "file",
2463
+ "globalDocumentReference",
2464
+ "image",
2465
+ "number",
2466
+ "object",
2467
+ "reference",
2468
+ "span",
2469
+ "string",
2470
+ "text",
2471
+ "url",
2472
+ "slug",
2473
+ "geopoint",
2474
+ "sanity.assetSourceData",
2475
+ "sanity.imageAsset",
2476
+ "sanity.fileAsset",
2477
+ "sanity.imageCrop",
2478
+ "sanity.imageHotspot",
2479
+ "sanity.imageMetadata",
2480
+ "sanity.imageDimensions",
2481
+ "sanity.imagePalette",
2482
+ "sanity.imagePaletteSwatch",
2483
+ assistSerializedTypeName,
2484
+ assistSerializedFieldTypeName,
2485
+ "sanity-agent.job.document"
2486
+ ], inlineTypes = ["document", "object", "image", "file"];
2487
+ function serializeSchema(schema, options2) {
2488
+ 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, options2)).filter((t) => !("to" in t && t.to && !t.to.length || "of" in t && t.of && !t.of.length || "fields" in t && t.fields && !t.fields.length));
2489
+ return list.sort((a, b) => (a?.name ?? "").localeCompare(b?.name ?? "")), list;
2490
+ }
2491
+ function getSchemaStub(schemaType, schema, options2) {
2492
+ if (!schemaType.type?.name)
2493
+ throw console.error("Missing type name", schemaType.type), new Error("Type is missing name!");
2494
+ const baseSchema = {
2495
+ // we dont need type or id when we send using POST, so leave these out to save bandwidth
2496
+ ...options2?.leanFormat ? {} : { _id: `${assistSchemaIdPrefix}${schemaType.name}`, _type: assistSerializedTypeName },
2497
+ name: schemaType.name,
2498
+ title: schemaType.title,
2499
+ type: schemaType.type.name,
2500
+ ...getBaseFields(schema, schemaType, schemaType.type.name, options2)
2501
+ };
2502
+ return removeUndef(baseSchema);
2503
+ }
2504
+ function getBaseFields(schema, type, typeName, options2) {
2505
+ const schemaOptions = removeUndef({
2506
+ imagePromptField: type.options?.aiAssist?.imageInstructionField,
2507
+ embeddingsIndex: type.options?.aiAssist?.embeddingsIndex
2508
+ });
2509
+ return removeUndef({
2510
+ options: Object.keys(schemaOptions).length ? schemaOptions : void 0,
2511
+ values: Array.isArray(type?.options?.list) ? type?.options?.list.map(
2512
+ (v) => typeof v == "string" ? v : v.value ?? `${v.title}`
2513
+ ) : void 0,
2514
+ of: "of" in type && typeName === "array" ? arrayOf(type, schema, options2) : void 0,
2515
+ to: "to" in type && typeName === "reference" ? refToTypeNames(type) : void 0,
2516
+ fields: "fields" in type && inlineTypes.includes(typeName) ? serializeFields(schema, type, options2) : void 0,
2517
+ annotations: typeName === "block" && "fields" in type ? serializeAnnotations(type, schema, options2) : void 0,
2518
+ inlineOf: typeName === "block" && "fields" in type ? serializeInlineOf(type, schema, options2) : void 0,
2519
+ hidden: typeof type.hidden == "function" ? "function" : type.hidden ? !0 : void 0,
2520
+ readOnly: typeof type.readOnly == "function" ? "function" : type.readOnly ? !0 : void 0
2521
+ });
2522
+ }
2523
+ function serializeFields(schema, schemaType, options2) {
2524
+ return (schemaType.fieldsets ? schemaType.fieldsets.flatMap(
2525
+ (fs) => fs.single ? fs.field : fs.fields.map((f) => ({
2526
+ ...f,
2527
+ type: {
2528
+ ...f.type,
2529
+ // if fieldset is (conditionally) hidden, the field must be considered the same way
2530
+ // ie, if the field does not show up in conditionalMembers, it is hidden
2531
+ // regardless of weather or not it is the field function or the fieldset function that hides it
2532
+ hidden: typeof fs.hidden == "function" ? fs.hidden : fs.hidden ? !0 : f.type.hidden
2533
+ }
2534
+ }))
2535
+ ) : schemaType.fields).filter((f) => !["sanity.imageHotspot", "sanity.imageCrop"].includes(f.type?.name ?? "")).filter((f) => isAssistSupported(f.type)).map((field) => serializeMember(schema, field.type, field.name, options2));
2536
+ }
2537
+ function serializeMember(schema, type, name, options2) {
2538
+ const typeName = schema.get(type?.name) ? type.name : type.type?.name ?? "";
2539
+ return removeUndef({
2540
+ ...options2?.leanFormat ? {} : { _type: assistSerializedFieldTypeName },
2541
+ name,
2542
+ type: typeName,
2543
+ title: type.title,
2544
+ ...getBaseFields(schema, type, typeName, options2)
2545
+ });
2546
+ }
2547
+ function serializeInlineOf(blockSchemaType, schema, options2) {
2548
+ const childrenType = blockSchemaType.fields.find((f) => f.name === "children")?.type;
2549
+ if (!(!childrenType || !isArraySchemaType(childrenType)))
2550
+ return arrayOf(
2551
+ {
2552
+ of: childrenType.of.filter((t) => !isType(t, "span"))
2553
+ },
2554
+ schema,
2555
+ options2
2556
+ );
2557
+ }
2558
+ function serializeAnnotations(blockSchemaType, schema, options2) {
2559
+ const marksType = blockSchemaType.fields.find((f) => f.name === "markDefs")?.type;
2560
+ if (!(!marksType || !isArraySchemaType(marksType)))
2561
+ return arrayOf(marksType, schema, options2);
2562
+ }
2563
+ function arrayOf(arrayType, schema, options2) {
2564
+ return arrayType.of.filter((type) => isAssistSupported(type)).map((t) => serializeMember(schema, t, t.name, options2));
2565
+ }
2566
+ function refToTypeNames(type) {
2567
+ return type.to.map((t) => ({
2568
+ type: typed(t.name)
2569
+ }));
2570
+ }
2571
+ function removeUndef(obj) {
2572
+ return Object.keys(obj).forEach((key) => obj[key] === void 0 ? delete obj[key] : {}), obj;
2573
+ }
2574
+ function createFieldRefCache() {
2575
+ const byType = {};
2576
+ function getRefsForType(schemaType) {
2577
+ const documentType = schemaType.name, cached = byType[documentType];
2578
+ if (cached) return cached;
2579
+ const fieldRefs = getFieldRefs(schemaType), fieldRefsByTypePath = asFieldRefsByTypePath(fieldRefs), refs = {
2580
+ fieldRefs,
2581
+ fieldRefsByTypePath
2582
+ };
2583
+ return byType[documentType] = refs, refs;
2584
+ }
2585
+ return getRefsForType;
2586
+ }
2587
+ function AiAssistanceConfigProvider(props) {
2588
+ const [status, setStatus] = useState(), [error, setError] = useState(), apiClient = useApiClient(props.config?.__customApiClient), { getInstructStatus, loading: statusLoading } = useGetInstructStatus(apiClient), { initInstruct, loading: initLoading } = useInitInstruct(apiClient), schema = useSchema(), serializedTypes = useMemo(() => serializeSchema(schema, { leanFormat: !0 }), [schema]), { getFieldRefs: getFieldRefs2, getFieldRefsByTypePath } = useFieldRefGetters(schema);
2589
+ useEffect(() => {
2590
+ getInstructStatus().then((s) => setStatus(s)).catch((e) => {
2591
+ console.error(e), setError(e);
2592
+ });
2593
+ }, [getInstructStatus]);
2594
+ const init = useCallback(async () => {
2595
+ setError(void 0);
2596
+ try {
2597
+ await initInstruct();
2598
+ const status2 = await getInstructStatus();
2599
+ setStatus(status2);
2600
+ } catch (e) {
2601
+ console.error("Failed to init ai assistance", e), setError(e);
2602
+ }
2603
+ }, [initInstruct, getInstructStatus, setStatus]), { config, children } = props, context = useMemo(() => ({
2604
+ config,
2605
+ status,
2606
+ statusLoading,
2607
+ init,
2608
+ initLoading,
2609
+ error,
2610
+ serializedTypes,
2611
+ getFieldRefs: getFieldRefs2,
2612
+ getFieldRefsByTypePath
2613
+ }), [
2614
+ config,
2615
+ status,
2616
+ init,
2617
+ statusLoading,
2618
+ initLoading,
2619
+ error,
2620
+ serializedTypes,
2621
+ getFieldRefs2,
2622
+ getFieldRefsByTypePath
2623
+ ]);
2624
+ return /* @__PURE__ */ jsx(AiAssistanceConfigContext.Provider, { value: context, children });
2625
+ }
2626
+ function useFieldRefGetters(schema) {
2627
+ return useMemo(() => {
2628
+ const getForSchemaType = createFieldRefCache();
2629
+ function getRefsForType(documentType) {
2630
+ const schemaType = schema.get(documentType);
2631
+ if (!schemaType)
2632
+ throw new Error(`Schema type "${documentType}" not found`);
2633
+ return getForSchemaType(schemaType);
2634
+ }
2635
+ return {
2636
+ getFieldRefs: (documentType) => getRefsForType(documentType).fieldRefs,
2637
+ getFieldRefsByTypePath: (documentType) => getRefsForType(documentType).fieldRefsByTypePath
2638
+ };
2639
+ }, [schema]);
2640
+ }
2605
2641
  function AssistLayout(props) {
2606
2642
  const [connectors, setConnectors] = useState([]);
2607
2643
  return /* @__PURE__ */ jsx(AiAssistanceConfigProvider, { config: props.config, children: /* @__PURE__ */ jsx(RunInstructionProvider, { children: /* @__PURE__ */ jsx(FieldTranslationProvider, { children: /* @__PURE__ */ jsxs(ConnectorsProvider, { onConnectorsChange: setConnectors, children: [
@@ -3187,7 +3223,7 @@ function BackToInstructionListLink() {
3187
3223
  }
3188
3224
  ) });
3189
3225
  }
3190
- const EMPTY_FIELDS = [];
3226
+ const SelectedFieldContext = createContext(void 0), SelectedFieldContextProvider = SelectedFieldContext.Provider, EMPTY_FIELDS = [];
3191
3227
  function AssistDocumentForm(props) {
3192
3228
  return props.readOnly ? /* @__PURE__ */ jsx(Card, { border: !0, tone: "caution", padding: 2, children: /* @__PURE__ */ jsx(Text, { size: 1, children: " You do not have sufficient permissions to manage instructions." }) }) : /* @__PURE__ */ jsx(AssistDocumentFormEditable, { ...props });
3193
3229
  }
@@ -3687,19 +3723,25 @@ const contextDocumentSchema = defineType({
3687
3723
  components: {
3688
3724
  input: FieldRefPathInput
3689
3725
  },
3690
- validation: (rule) => rule.custom((value, context) => {
3691
- if (!value)
3692
- return "Please select a field";
3693
- try {
3694
- const docId = context.document?._id;
3695
- if (!docId)
3696
- return "Field reference cannot be used outside document inspector context. Could not resolve document id.";
3697
- const targetDocType = docId.replace(new RegExp(`^${assistDocumentIdPrefix}`), ""), schema = context.schema.get(targetDocType);
3698
- return schema ? getFieldRefsWithDocument(schema).find((r) => r.key === value) ? !0 : `Field with path "${value}" does not exist in the schema.` : `Field reference cannot be used outside document inspector context. Could not resolve schema: ${targetDocType}`;
3699
- } catch (e) {
3700
- return console.error("Failed to resolve field reference", e), "Invalid field reference.";
3701
- }
3702
- })
3726
+ validation: (rule) => {
3727
+ const getForSchemaType = createFieldRefCache();
3728
+ return rule.custom((value, context) => {
3729
+ if (!value)
3730
+ return "Please select a field";
3731
+ try {
3732
+ const docId = context.document?._id;
3733
+ if (!docId)
3734
+ return "Field reference cannot be used outside document inspector context. Could not resolve document id.";
3735
+ const targetDocType = docId.replace(new RegExp(`^${assistDocumentIdPrefix}`), ""), schema = context.schema.get(targetDocType);
3736
+ if (!schema)
3737
+ return `Field reference cannot be used outside document inspector context. Could not resolve schema: ${targetDocType}`;
3738
+ const { fieldRefs } = getForSchemaType(schema);
3739
+ return fieldRefs.find((r) => r.key === value) ? !0 : `Field with path "${value}" does not exist in the schema.`;
3740
+ } catch (e) {
3741
+ return console.error("Failed to resolve field reference", e), "Invalid field reference.";
3742
+ }
3743
+ });
3744
+ }
3703
3745
  })
3704
3746
  ],
3705
3747
  preview: {