@sanity/assist 2.0.4-canary.0 → 2.0.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.
Files changed (91) hide show
  1. package/README.md +233 -214
  2. package/dist/index.esm.js +1769 -1769
  3. package/dist/index.esm.js.map +1 -1
  4. package/dist/index.js +1767 -1767
  5. package/dist/index.js.map +1 -1
  6. package/package.json +17 -18
  7. package/src/_lib/connector/ConnectFromRegion.tsx +4 -3
  8. package/src/_lib/connector/ConnectToRegion.tsx +1 -0
  9. package/src/_lib/connector/ConnectorRegion.tsx +2 -1
  10. package/src/_lib/connector/ConnectorsProvider.tsx +2 -1
  11. package/src/_lib/connector/ConnectorsStoreContext.ts +1 -0
  12. package/src/_lib/connector/index.ts +1 -1
  13. package/src/_lib/connector/mapConnectorToLine.ts +2 -2
  14. package/src/_lib/connector/useConnectorsStore.ts +2 -1
  15. package/src/_lib/connector/useRegionRects.ts +4 -3
  16. package/src/_lib/fixedListenQuery.ts +11 -11
  17. package/src/_lib/form/DocumentForm.tsx +4 -3
  18. package/src/_lib/form/helpers.ts +2 -1
  19. package/src/_lib/useListeningQuery.ts +4 -3
  20. package/src/assistConnectors/AssistConnectorsOverlay.tsx +1 -0
  21. package/src/assistConnectors/ConnectorPath.tsx +3 -2
  22. package/src/assistConnectors/draw/connectorPath.ts +13 -13
  23. package/src/assistDocument/AssistDocumentContext.tsx +3 -2
  24. package/src/assistDocument/AssistDocumentContextProvider.tsx +2 -1
  25. package/src/assistDocument/AssistDocumentInput.tsx +9 -8
  26. package/src/assistDocument/RequestRunInstructionProvider.tsx +4 -3
  27. package/src/assistDocument/components/AssistDocumentForm.tsx +25 -24
  28. package/src/assistDocument/components/FieldRefPreview.tsx +4 -3
  29. package/src/assistDocument/components/InstructionsArrayInput.tsx +4 -3
  30. package/src/assistDocument/components/SelectedFieldContext.tsx +1 -1
  31. package/src/assistDocument/components/helpers.ts +4 -4
  32. package/src/assistDocument/components/instruction/BackToInstructionsLink.tsx +3 -2
  33. package/src/assistDocument/components/instruction/FieldRefInput.tsx +5 -4
  34. package/src/assistDocument/components/instruction/InstructionInput.tsx +3 -2
  35. package/src/assistDocument/components/instruction/InstructionOutputField.tsx +2 -1
  36. package/src/assistDocument/components/instruction/InstructionOutputInput.tsx +14 -13
  37. package/src/assistDocument/components/instruction/PromptInput.tsx +4 -3
  38. package/src/assistDocument/components/instruction/appearance/IconInput.tsx +2 -2
  39. package/src/assistDocument/components/instruction/appearance/InstructionVisibility.tsx +1 -1
  40. package/src/assistDocument/hooks/useAssistDocumentContextValue.tsx +7 -6
  41. package/src/assistDocument/hooks/useInstructionToaster.tsx +6 -5
  42. package/src/assistDocument/hooks/useStudioAssistDocument.ts +14 -13
  43. package/src/assistFormComponents/AssistField.tsx +9 -8
  44. package/src/assistFormComponents/AssistFormBlock.tsx +5 -4
  45. package/src/assistFormComponents/AssistInlineFormBlock.tsx +1 -1
  46. package/src/assistFormComponents/AssistItem.tsx +3 -2
  47. package/src/assistFormComponents/validation/listItem.tsx +2 -2
  48. package/src/assistFormComponents/validation/validationList.tsx +3 -2
  49. package/src/assistInspector/AssistInspector.tsx +16 -15
  50. package/src/assistInspector/FieldAutocomplete.tsx +4 -3
  51. package/src/assistInspector/InstructionTaskHistoryButton.tsx +19 -18
  52. package/src/assistInspector/helpers.ts +10 -9
  53. package/src/assistInspector/index.ts +4 -3
  54. package/src/assistLayout/AiAssistanceConfigContext.tsx +1 -0
  55. package/src/assistLayout/AssistLayout.tsx +5 -4
  56. package/src/assistLayout/RunInstructionProvider.tsx +18 -15
  57. package/src/components/FadeInContent.tsx +1 -1
  58. package/src/components/HideReferenceChangedBannerInput.tsx +1 -1
  59. package/src/components/ImageContext.tsx +4 -3
  60. package/src/components/SafeValueInput.tsx +7 -6
  61. package/src/components/TimeAgo.tsx +1 -1
  62. package/src/fieldActions/assistFieldActions.tsx +31 -30
  63. package/src/fieldActions/generateCaptionActions.tsx +8 -7
  64. package/src/fieldActions/generateImageActions.tsx +6 -5
  65. package/src/helpers/assistSupported.ts +1 -0
  66. package/src/helpers/conditionalMembers.test.ts +2 -1
  67. package/src/helpers/conditionalMembers.ts +17 -14
  68. package/src/helpers/misc.ts +3 -2
  69. package/src/helpers/typeUtils.ts +1 -1
  70. package/src/helpers/useAssistSupported.ts +2 -1
  71. package/src/onboarding/FieldActionsOnboarding.tsx +2 -1
  72. package/src/onboarding/FirstAssistedPathProvider.tsx +4 -3
  73. package/src/onboarding/InspectorOnboarding.tsx +3 -2
  74. package/src/onboarding/onboardingStore.ts +1 -1
  75. package/src/presence/AiFieldPresence.tsx +3 -1
  76. package/src/presence/AssistDocumentPresence.tsx +7 -6
  77. package/src/presence/useAssistPresence.ts +6 -3
  78. package/src/schemas/assistDocumentSchema.tsx +21 -20
  79. package/src/schemas/contextDocumentSchema.tsx +3 -2
  80. package/src/schemas/index.ts +2 -1
  81. package/src/schemas/serialize/SchemTypeTool.tsx +4 -3
  82. package/src/schemas/serialize/serializeSchema.test.ts +3 -2
  83. package/src/schemas/serialize/serializeSchema.ts +15 -14
  84. package/src/schemas/serializedSchemaTypeSchema.ts +2 -1
  85. package/src/translate/FieldTranslationProvider.tsx +33 -25
  86. package/src/translate/getLanguageParams.ts +3 -3
  87. package/src/translate/paths.test.ts +11 -4
  88. package/src/translate/paths.ts +12 -11
  89. package/src/translate/translateActions.tsx +12 -11
  90. package/src/translate/types.ts +2 -2
  91. package/src/useApiClient.ts +9 -9
package/dist/index.js CHANGED
@@ -4,18 +4,18 @@ Object.defineProperty(exports, '__esModule', {
4
4
  value: true
5
5
  });
6
6
  var jsxRuntime = require('react/jsx-runtime');
7
- var sanity = require('sanity');
7
+ var icons = require('@sanity/icons');
8
8
  var ui = require('@sanity/ui');
9
9
  var react = require('react');
10
- var icons = require('@sanity/icons');
11
- var operators = require('rxjs/operators');
10
+ var sanity = require('sanity');
12
11
  var isEqual = require('react-fast-compare');
12
+ var operators = require('rxjs/operators');
13
13
  var rxjs = require('rxjs');
14
14
  var rxjsExhaustmapWithTrailing = require('rxjs-exhaustmap-with-trailing');
15
15
  var mutator = require('@sanity/mutator');
16
+ var dateFns = require('date-fns');
16
17
  var desk = require('sanity/desk');
17
18
  var styled = require('styled-components');
18
- var dateFns = require('date-fns');
19
19
  var formatDistanceToNow = require('date-fns/formatDistanceToNow');
20
20
  function _interopDefaultCompat(e) {
21
21
  return e && typeof e === 'object' && 'default' in e ? e : {
@@ -25,27 +25,6 @@ function _interopDefaultCompat(e) {
25
25
  var isEqual__default = /*#__PURE__*/_interopDefaultCompat(isEqual);
26
26
  var styled__default = /*#__PURE__*/_interopDefaultCompat(styled);
27
27
  var formatDistanceToNow__default = /*#__PURE__*/_interopDefaultCompat(formatDistanceToNow);
28
- const assistDocumentIdPrefix = "sanity.assist.schemaType.";
29
- const assistDocumentStatusIdPrefix = "sanity.assist.status.";
30
- const assistSchemaIdPrefix = "sanity.assist.schema.";
31
- const assistDocumentTypeName = "sanity.assist.schemaType.annotations";
32
- const assistFieldTypeName = "sanity.assist.schemaType.field";
33
- const instructionTypeName = "sanity.assist.instruction";
34
- const promptTypeName = "sanity.assist.instruction.prompt";
35
- const userInputTypeName = "sanity.assist.instruction.userInput";
36
- const instructionContextTypeName = "sanity.assist.instruction.context";
37
- const fieldReferenceTypeName = "sanity.assist.instruction.fieldRef";
38
- const contextDocumentTypeName = "assist.instruction.context";
39
- const assistTasksStatusTypeName = "sanity.assist.task.status";
40
- const instructionTaskTypeName = "sanity.assist.instructionTask";
41
- const fieldPresenceTypeName = "sanity.assist.instructionTask.presence";
42
- const assistSerializedTypeName = "sanity.assist.serialized.type";
43
- const assistSerializedFieldTypeName = "sanity.assist.serialized.field";
44
- const outputFieldTypeName = "sanity.assist.output.field";
45
- const outputTypeTypeName = "sanity.assist.output.type";
46
- const fieldPathParam = "pathKey";
47
- const instructionParam = "instruction";
48
- const documentRootKey = "<document>";
49
28
  const fetch = (client, query, params, options) => rxjs.defer(() =>
50
29
  // getVersionedClient(options.apiVersion)
51
30
  client.observable.fetch(query, params, {
@@ -123,7 +102,27 @@ function useListeningQuery(query) {
123
102
  data
124
103
  };
125
104
  }
126
- const hiddenTypes = ["any", "array", "block", "boolean", "crossDatasetReference", "date", "datetime", "document", "email", "file", "image", "number", "object", "reference", "span", "string", "text", "url", "slug", "geopoint", "sanity.assetSourceData", "sanity.imageAsset", "sanity.fileAsset", "sanity.imageCrop", "sanity.imageHotspot", "sanity.imageMetadata", "sanity.imageDimensions", "sanity.imagePalette", "sanity.imagePaletteSwatch", assistSerializedTypeName, assistSerializedFieldTypeName, "sanity-agent.job.document"];
105
+ const assistDocumentIdPrefix = "sanity.assist.schemaType.";
106
+ const assistDocumentStatusIdPrefix = "sanity.assist.status.";
107
+ const assistSchemaIdPrefix = "sanity.assist.schema.";
108
+ const assistDocumentTypeName = "sanity.assist.schemaType.annotations";
109
+ const assistFieldTypeName = "sanity.assist.schemaType.field";
110
+ const instructionTypeName = "sanity.assist.instruction";
111
+ const promptTypeName = "sanity.assist.instruction.prompt";
112
+ const userInputTypeName = "sanity.assist.instruction.userInput";
113
+ const instructionContextTypeName = "sanity.assist.instruction.context";
114
+ const fieldReferenceTypeName = "sanity.assist.instruction.fieldRef";
115
+ const contextDocumentTypeName = "assist.instruction.context";
116
+ const assistTasksStatusTypeName = "sanity.assist.task.status";
117
+ const instructionTaskTypeName = "sanity.assist.instructionTask";
118
+ const fieldPresenceTypeName = "sanity.assist.instructionTask.presence";
119
+ const assistSerializedTypeName = "sanity.assist.serialized.type";
120
+ const assistSerializedFieldTypeName = "sanity.assist.serialized.field";
121
+ const outputFieldTypeName = "sanity.assist.output.field";
122
+ const outputTypeTypeName = "sanity.assist.output.type";
123
+ const fieldPathParam = "pathKey";
124
+ const instructionParam = "instruction";
125
+ const documentRootKey = "<document>";
127
126
  function isPortableTextArray(type) {
128
127
  return type.of.find(t => isType(t, "block"));
129
128
  }
@@ -189,6 +188,7 @@ function isUnsupportedType(type) {
189
188
  var _a, _b;
190
189
  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");
191
190
  }
191
+ const hiddenTypes = ["any", "array", "block", "boolean", "crossDatasetReference", "date", "datetime", "document", "email", "file", "image", "number", "object", "reference", "span", "string", "text", "url", "slug", "geopoint", "sanity.assetSourceData", "sanity.imageAsset", "sanity.fileAsset", "sanity.imageCrop", "sanity.imageHotspot", "sanity.imageMetadata", "sanity.imageDimensions", "sanity.imagePalette", "sanity.imagePaletteSwatch", assistSerializedTypeName, assistSerializedFieldTypeName, "sanity-agent.job.document"];
192
192
  const inlineTypes = ["document", "object", "image", "file"];
193
193
  function serializeSchema(schema, options) {
194
194
  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 => {
@@ -519,7 +519,14 @@ function getFieldLanguageMap(documentSchema, documentMembers, translateFromLangu
519
519
  }
520
520
  return translationMaps;
521
521
  }
522
- const aiInspectorId = "ai-assistance";
522
+ const releaseAnnouncementUrl = "https://www.sanity.io/blog/sanity-ai-assist-announcement?utm_source=sanity-assist-plugin&utm_medium=organic_social&utm_campaign=ai-assist&utm_content=";
523
+ const instructionGuideUrl = "https://sanity.io/guides/getting-started-with-ai-assist-instructions?utm_source=sanity-assist-plugin&utm_medium=organic_social&utm_campaign=ai-assist&utm_content=";
524
+ const giveFeedbackUrl = "https://forms.gle/Kwz7CThxGeA2GiEU8";
525
+ const salesUrl = "https://www.sanity.io/contact/sales?utm_source=sanity-assist-plugin&utm_medium=organic_social&utm_campaign=ai-assist&utm_content=";
526
+ const packageName = "@sanity/assist";
527
+ const pluginTitle = "Sanity AI Assist";
528
+ const pluginTitleShort = "AI Assist";
529
+ const maxHistoryVisibilityMs = dateFns.minutesToMilliseconds(30);
523
530
  const assistFormId = "assist";
524
531
  const preventDefault = ev => ev.preventDefault();
525
532
  function DocumentForm(props) {
@@ -797,334 +804,107 @@ function useAiPaneRouter() {
797
804
  };
798
805
  }, [paneRouter]);
799
806
  }
800
- function useDocumentState(id, docType) {
801
- const state = sanity.useEditState(id, docType);
802
- return state.draft || state.published;
803
- }
804
- const aiDocPrefixPattern = new RegExp("^".concat(assistDocumentIdPrefix));
805
- function publicId(id) {
806
- return id.replace("drafts.", "");
807
- }
808
- function assistDocumentId(documentType) {
809
- return "".concat(assistDocumentIdPrefix).concat(documentType);
810
- }
811
- function documentTypeFromAiDocumentId(id) {
812
- return id.replace(aiDocPrefixPattern, "");
813
- }
814
- function assistTasksStatusId(documentId) {
815
- return "".concat(assistDocumentStatusIdPrefix).concat(publicId(documentId));
807
+ const basePath = "/assist/tasks/instruction";
808
+ function canUseAssist(status) {
809
+ return (status == null ? void 0 : status.enabled) && status.initialized && status.validToken;
816
810
  }
817
- const releaseAnnouncementUrl = "https://www.sanity.io/blog/sanity-ai-assist-announcement?utm_source=sanity-assist-plugin&utm_medium=organic_social&utm_campaign=ai-assist&utm_content=";
818
- const instructionGuideUrl = "https://sanity.io/guides/getting-started-with-ai-assist-instructions?utm_source=sanity-assist-plugin&utm_medium=organic_social&utm_campaign=ai-assist&utm_content=";
819
- const giveFeedbackUrl = "https://forms.gle/Kwz7CThxGeA2GiEU8";
820
- const salesUrl = "https://www.sanity.io/contact/sales?utm_source=sanity-assist-plugin&utm_medium=organic_social&utm_campaign=ai-assist&utm_content=";
821
- const packageName = "@sanity/assist";
822
- const pluginTitle = "Sanity AI Assist";
823
- const pluginTitleShort = "AI Assist";
824
- const maxHistoryVisibilityMs = dateFns.minutesToMilliseconds(30);
825
- function useStudioAssistDocument(_ref2) {
826
- let {
827
- documentId,
828
- schemaType,
829
- initDoc
830
- } = _ref2;
831
- const documentTypeName = schemaType.name;
832
- const currentUser = sanity.useCurrentUser();
833
- const assistDocument = useDocumentState(assistDocumentId(documentTypeName), assistDocumentTypeName);
834
- const assistTasksStatus = useDocumentState(assistTasksStatusId(documentId != null ? documentId : ""), assistTasksStatusTypeName);
811
+ function useApiClient(customApiClient) {
835
812
  const client = sanity.useClient({
836
- apiVersion: "2023-01-01"
837
- });
838
- react.useEffect(() => {
839
- if (!assistDocument && initDoc) {
840
- client.createIfNotExists({
841
- _id: assistDocumentId(documentTypeName),
842
- _type: assistDocumentTypeName
843
- }).catch(e => {});
844
- }
845
- }, [client, assistDocument, documentTypeName, initDoc]);
846
- return react.useMemo(() => {
847
- var _a, _b;
848
- if (!assistDocument) {
849
- return void 0;
850
- }
851
- const tasks = (_a = assistTasksStatus == null ? void 0 : assistTasksStatus.tasks) != null ? _a : [];
852
- const fields = ((_b = assistDocument == null ? void 0 : assistDocument.fields) != null ? _b : []).map(assistField => {
853
- var _a2;
854
- return {
855
- ...assistField,
856
- tasks: tasks.filter(task => task.path === assistField.path),
857
- 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))
858
- };
859
- });
860
- return sanity.typed({
861
- ...assistDocument,
862
- tasks: tasks == null ? void 0 : tasks.map(task => {
863
- var _a2, _b2;
864
- const instruction = (_b2 = (_a2 = fields.find(f => f.path === task.path)) == null ? void 0 : _a2.instructions) == null ? void 0 : _b2.find(i => i._key === task.instructionKey);
865
- return {
866
- ...task,
867
- instruction
868
- };
869
- }),
870
- fields
871
- });
872
- }, [assistDocument, assistTasksStatus, currentUser]);
873
- }
874
- function asStudioInstruction(instruction, run) {
875
- return {
876
- ...instruction,
877
- tasks: run.filter(task => task.instructionKey === instruction._key).filter(task => task.started && ( /* @__PURE__ */new Date()).getTime() - new Date(task.started).getTime() < maxHistoryVisibilityMs)
878
- };
879
- }
880
- function useInterval(ms) {
881
- const [tick, update] = react.useReducer(n => n + 1, 0);
882
- react.useEffect(() => {
883
- const i = setInterval(update, ms);
884
- return () => clearInterval(i);
885
- }, [ms]);
886
- return tick;
887
- }
888
- function TimeAgo(_ref3) {
889
- let {
890
- date
891
- } = _ref3;
892
- useInterval(1e3);
893
- const timeSince = formatDistanceToNow__default.default(date ? new Date(date) : /* @__PURE__ */new Date());
894
- return /* @__PURE__ */jsxRuntime.jsxs("span", {
895
- title: timeSince,
896
- children: [timeSince, " ago"]
813
+ apiVersion: "2023-06-05"
897
814
  });
815
+ return react.useMemo(() => customApiClient ? customApiClient(client) : client, [client, customApiClient]);
898
816
  }
899
- function usePathKey(path) {
900
- return react.useMemo(() => {
901
- return getPathKey(path);
902
- }, [path]);
903
- }
904
- function getPathKey(path) {
905
- if (path.length) {
906
- return Array.isArray(path) ? sanity.pathToString(path) : path;
907
- }
908
- return documentRootKey;
817
+ function useTranslate(apiClient) {
818
+ const [loading, setLoading] = react.useState(false);
819
+ const user = sanity.useCurrentUser();
820
+ const schema = sanity.useSchema();
821
+ const types = react.useMemo(() => serializeSchema(schema, {
822
+ leanFormat: true
823
+ }), [schema]);
824
+ const toast = ui.useToast();
825
+ const translate = react.useCallback(_ref2 => {
826
+ let {
827
+ documentId,
828
+ languagePath,
829
+ translatePath,
830
+ fieldLanguageMap,
831
+ conditionalMembers
832
+ } = _ref2;
833
+ setLoading(true);
834
+ return apiClient.request({
835
+ method: "POST",
836
+ url: "/assist/tasks/translate/".concat(apiClient.config().dataset, "?projectId=").concat(apiClient.config().projectId),
837
+ body: {
838
+ documentId,
839
+ types,
840
+ languagePath,
841
+ fieldLanguageMap,
842
+ conditionalMembers,
843
+ translatePath: translatePath.length === 0 ? documentRootKey : sanity.pathToString(translatePath),
844
+ userId: user == null ? void 0 : user.id
845
+ }
846
+ }).catch(e => {
847
+ toast.push({
848
+ status: "error",
849
+ title: "Translate failed",
850
+ description: e.message
851
+ });
852
+ setLoading(false);
853
+ throw e;
854
+ }).finally(() => {
855
+ setTimeout(() => {
856
+ setLoading(false);
857
+ }, 2e3);
858
+ });
859
+ }, [setLoading, apiClient, toast, user, types]);
860
+ return react.useMemo(() => ({
861
+ translate,
862
+ loading
863
+ }), [translate, loading]);
909
864
  }
910
- function getInstructionTitle(instruction) {
911
- var _a;
912
- return (_a = instruction == null ? void 0 : instruction.title) != null ? _a : "Untitled";
865
+ function useGenerateCaption(apiClient) {
866
+ const [loading, setLoading] = react.useState(false);
867
+ const user = sanity.useCurrentUser();
868
+ const schema = sanity.useSchema();
869
+ const types = react.useMemo(() => serializeSchema(schema, {
870
+ leanFormat: true
871
+ }), [schema]);
872
+ const toast = ui.useToast();
873
+ const generateCaption = react.useCallback(_ref3 => {
874
+ let {
875
+ path,
876
+ documentId
877
+ } = _ref3;
878
+ setLoading(true);
879
+ return apiClient.request({
880
+ method: "POST",
881
+ url: "/assist/tasks/generate-caption/".concat(apiClient.config().dataset, "?projectId=").concat(apiClient.config().projectId),
882
+ body: {
883
+ path,
884
+ documentId,
885
+ types,
886
+ userId: user == null ? void 0 : user.id
887
+ }
888
+ }).catch(e => {
889
+ toast.push({
890
+ status: "error",
891
+ title: "Generate image description failed",
892
+ description: e.message
893
+ });
894
+ setLoading(false);
895
+ throw e;
896
+ }).finally(() => {
897
+ setTimeout(() => {
898
+ setLoading(false);
899
+ }, 2e3);
900
+ });
901
+ }, [setLoading, apiClient, toast, user, types]);
902
+ return react.useMemo(() => ({
903
+ generateCaption,
904
+ loading
905
+ }), [generateCaption, loading]);
913
906
  }
914
- var __freeze$5 = Object.freeze;
915
- var __defProp$5 = Object.defineProperty;
916
- var __template$5 = (cooked, raw) => __freeze$5(__defProp$5(cooked, "raw", {
917
- value: __freeze$5(raw || cooked.slice())
918
- }));
919
- var _a$5, _b$3;
920
- const rotate = styled.keyframes(_a$5 || (_a$5 = __template$5(["\n 0% {\n transform: rotate(0);\n }\n 100% {\n transform: rotate(360deg);\n }\n"])));
921
- const SyncSpinningIcon = styled__default.default(icons.SyncIcon)(_b$3 || (_b$3 = __template$5(["\n animation: ", " 1s linear infinite;\n"])), rotate);
922
- const TASK_CONFIG = {
923
- aborted: {
924
- title: "Canceled",
925
- icon: icons.CloseCircleIcon,
926
- tone: "transparent"
927
- },
928
- error: {
929
- title: "Error",
930
- icon: icons.ErrorOutlineIcon,
931
- tone: "critical"
932
- },
933
- success: {
934
- title: "Completed",
935
- icon: icons.CheckmarkCircleIcon,
936
- tone: "positive"
937
- },
938
- timeout: {
939
- title: "Timeout",
940
- icon: icons.ClockIcon,
941
- tone: "caution"
942
- }
943
- };
944
- function InstructionTaskHistoryButton(props) {
945
- const {
946
- tasks,
947
- instructions,
948
- documentId,
949
- showTitles
950
- } = props;
951
- const client = sanity.useClient({
952
- apiVersion: "2023-01-01"
953
- });
954
- const cancelRun = react.useCallback(taskKey => {
955
- if (!documentId) {
956
- return;
957
- }
958
- const statusDocId = assistTasksStatusId(documentId);
959
- const basePath = "".concat(sanity.typed("tasks"), '[_key=="').concat(taskKey, '"]');
960
- client.patch(statusDocId).set({
961
- ["".concat(basePath, ".").concat(sanity.typed("ended"))]: ( /* @__PURE__ */new Date()).toISOString(),
962
- ["".concat(basePath, ".").concat(sanity.typed("reason"))]: sanity.typed("aborted")
963
- }).commit().catch(console.error);
964
- }, [client, documentId]);
965
- const titledTasks = react.useMemo(() => {
966
- var _a2;
967
- const t = (_a2 = tasks == null ? void 0 : tasks.filter(task => task.started && ( /* @__PURE__ */new Date()).getTime() - new Date(task.started).getTime() < maxHistoryVisibilityMs).map(task => {
968
- var _a3;
969
- const instruction = instructions == null ? void 0 : instructions.find(i => i._key === task.instructionKey);
970
- return {
971
- ...task,
972
- title: showTitles ? (_a3 = task.title) != null ? _a3 : getInstructionTitle(instruction) : void 0,
973
- cancel: () => cancelRun(task._key)
974
- };
975
- })) != null ? _a2 : [];
976
- t.sort((a, b) => {
977
- var _a3, _b2;
978
- return new Date((_a3 = b.started) != null ? _a3 : "").getTime() - new Date((_b2 = a.started) != null ? _b2 : "").getTime();
979
- });
980
- return t;
981
- }, [tasks, instructions, cancelRun, showTitles]);
982
- const isRunning = react.useMemo(() => titledTasks.some(r => !r.ended), [titledTasks]);
983
- const hasErrors = react.useMemo(() => titledTasks.some(r => r.reason === "error" || r.reason === "timeout"), [titledTasks]);
984
- const [open, setOpen] = react.useState(false);
985
- const toggleOpen = react.useCallback(() => setOpen(v => !v), []);
986
- const [button, setButton] = react.useState(null);
987
- const [popover, setPopover] = react.useState(null);
988
- const handleClickOutside = react.useCallback(() => {
989
- setOpen(false);
990
- }, []);
991
- ui.useClickOutside(handleClickOutside, [button, popover]);
992
- const handleEscape = react.useCallback(() => {
993
- setOpen(false);
994
- button == null ? void 0 : button.focus();
995
- }, [button]);
996
- return /* @__PURE__ */jsxRuntime.jsx(ui.Popover, {
997
- constrainSize: true,
998
- content: /* @__PURE__ */jsxRuntime.jsx(TaskList, {
999
- onEscape: handleEscape,
1000
- tasks: titledTasks
1001
- }),
1002
- open: open && !!(titledTasks == null ? void 0 : titledTasks.length),
1003
- placement: "top",
1004
- portal: true,
1005
- ref: setPopover,
1006
- width: 0,
1007
- children: /* @__PURE__ */jsxRuntime.jsx(TaskStatusButton, {
1008
- disabled: !(titledTasks == null ? void 0 : titledTasks.length),
1009
- hasErrors,
1010
- isRunning,
1011
- onClick: toggleOpen,
1012
- ref: setButton,
1013
- selected: open
1014
- })
1015
- });
1016
- }
1017
- const TASK_STATUS_BUTTON_TOOLTIP_PROPS = {
1018
- placement: "top"
1019
- };
1020
- const TaskStatusButton = react.forwardRef(function TaskStatusButton2(props, ref) {
1021
- const {
1022
- disabled,
1023
- hasErrors,
1024
- isRunning,
1025
- onClick,
1026
- selected
1027
- } = props;
1028
- return /* @__PURE__ */jsxRuntime.jsx(sanity.StatusButton, {
1029
- label: "".concat(pluginTitle, " status"),
1030
- icon: isRunning ? SyncSpinningIcon : hasErrors ? icons.ErrorOutlineIcon : icons.CheckmarkCircleIcon,
1031
- mode: "bleed",
1032
- onClick,
1033
- tone: hasErrors ? "critical" : void 0,
1034
- disabled,
1035
- ref,
1036
- selected,
1037
- tooltipProps: TASK_STATUS_BUTTON_TOOLTIP_PROPS
1038
- });
1039
- });
1040
- function TaskList(props) {
1041
- const {
1042
- onEscape,
1043
- tasks
1044
- } = props;
1045
- const {
1046
- isTopLayer
1047
- } = ui.useLayer();
1048
- ui.useGlobalKeyDown(react.useCallback(event => {
1049
- if (isTopLayer && event.key === "Escape") {
1050
- onEscape();
1051
- }
1052
- }, [isTopLayer, onEscape]));
1053
- return /* @__PURE__ */jsxRuntime.jsx(ui.Stack, {
1054
- padding: 1,
1055
- space: 1,
1056
- children: tasks.map(task => /* @__PURE__ */jsxRuntime.jsx(TaskItem, {
1057
- task
1058
- }, task._key))
1059
- });
1060
- }
1061
- function TaskItem(props) {
1062
- var _a2;
1063
- const {
1064
- task
1065
- } = props;
1066
- const taskType = task.reason && TASK_CONFIG[task.reason];
1067
- return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
1068
- radius: 2,
1069
- tone: taskType && (taskType == null ? void 0 : taskType.tone),
1070
- children: /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
1071
- align: "center",
1072
- gap: 1,
1073
- children: [/* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
1074
- align: "flex-start",
1075
- flex: 1,
1076
- gap: 3,
1077
- padding: 3,
1078
- children: [/* @__PURE__ */jsxRuntime.jsx(ui.Box, {
1079
- flex: "none",
1080
- children: /* @__PURE__ */jsxRuntime.jsxs(ui.Text, {
1081
- size: 1,
1082
- children: [taskType && react.createElement(taskType.icon), !task.reason && /* @__PURE__ */jsxRuntime.jsx(ui.Spinner, {})]
1083
- })
1084
- }), /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
1085
- flex: 1,
1086
- space: 2,
1087
- children: [/* @__PURE__ */jsxRuntime.jsxs(ui.Text, {
1088
- size: 1,
1089
- weight: "medium",
1090
- children: [taskType ? taskType.title : "Running", task.title && /* @__PURE__ */jsxRuntime.jsxs(jsxRuntime.Fragment, {
1091
- children: [": ", task.title]
1092
- })]
1093
- }), task.message ? /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
1094
- size: 1,
1095
- children: task.message
1096
- }) : null, /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
1097
- muted: true,
1098
- size: 1,
1099
- children: /* @__PURE__ */jsxRuntime.jsx(TimeAgo, {
1100
- date: (_a2 = task.ended) != null ? _a2 : task.started
1101
- })
1102
- })]
1103
- })]
1104
- }), !task.ended && /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
1105
- flex: "none",
1106
- padding: 1,
1107
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
1108
- fontSize: 1,
1109
- mode: "bleed",
1110
- onClick: task.cancel,
1111
- text: "Cancel"
1112
- })
1113
- })]
1114
- })
1115
- });
1116
- }
1117
- const basePath = "/assist/tasks/instruction";
1118
- function canUseAssist(status) {
1119
- return (status == null ? void 0 : status.enabled) && status.initialized && status.validToken;
1120
- }
1121
- function useApiClient(customApiClient) {
1122
- const client = sanity.useClient({
1123
- apiVersion: "2023-06-05"
1124
- });
1125
- return react.useMemo(() => customApiClient ? customApiClient(client) : client, [client, customApiClient]);
1126
- }
1127
- function useTranslate(apiClient) {
907
+ function useGenerateImage(apiClient) {
1128
908
  const [loading, setLoading] = react.useState(false);
1129
909
  const user = sanity.useCurrentUser();
1130
910
  const schema = sanity.useSchema();
@@ -1132,31 +912,25 @@ function useTranslate(apiClient) {
1132
912
  leanFormat: true
1133
913
  }), [schema]);
1134
914
  const toast = ui.useToast();
1135
- const translate = react.useCallback(_ref4 => {
915
+ const generateImage = react.useCallback(_ref4 => {
1136
916
  let {
1137
- documentId,
1138
- languagePath,
1139
- translatePath,
1140
- fieldLanguageMap,
1141
- conditionalMembers
917
+ path,
918
+ documentId
1142
919
  } = _ref4;
1143
920
  setLoading(true);
1144
921
  return apiClient.request({
1145
922
  method: "POST",
1146
- url: "/assist/tasks/translate/".concat(apiClient.config().dataset, "?projectId=").concat(apiClient.config().projectId),
923
+ url: "/assist/tasks/generate-image/".concat(apiClient.config().dataset, "?projectId=").concat(apiClient.config().projectId),
1147
924
  body: {
925
+ path,
1148
926
  documentId,
1149
927
  types,
1150
- languagePath,
1151
- fieldLanguageMap,
1152
- conditionalMembers,
1153
- translatePath: translatePath.length === 0 ? documentRootKey : sanity.pathToString(translatePath),
1154
928
  userId: user == null ? void 0 : user.id
1155
929
  }
1156
930
  }).catch(e => {
1157
931
  toast.push({
1158
932
  status: "error",
1159
- title: "Translate failed",
933
+ title: "Generate image from prompt failed",
1160
934
  description: e.message
1161
935
  });
1162
936
  setLoading(false);
@@ -1168,97 +942,13 @@ function useTranslate(apiClient) {
1168
942
  });
1169
943
  }, [setLoading, apiClient, toast, user, types]);
1170
944
  return react.useMemo(() => ({
1171
- translate,
945
+ generateImage,
1172
946
  loading
1173
- }), [translate, loading]);
947
+ }), [generateImage, loading]);
1174
948
  }
1175
- function useGenerateCaption(apiClient) {
1176
- const [loading, setLoading] = react.useState(false);
1177
- const user = sanity.useCurrentUser();
1178
- const schema = sanity.useSchema();
1179
- const types = react.useMemo(() => serializeSchema(schema, {
1180
- leanFormat: true
1181
- }), [schema]);
1182
- const toast = ui.useToast();
1183
- const generateCaption = react.useCallback(_ref5 => {
1184
- let {
1185
- path,
1186
- documentId
1187
- } = _ref5;
1188
- setLoading(true);
1189
- return apiClient.request({
1190
- method: "POST",
1191
- url: "/assist/tasks/generate-caption/".concat(apiClient.config().dataset, "?projectId=").concat(apiClient.config().projectId),
1192
- body: {
1193
- path,
1194
- documentId,
1195
- types,
1196
- userId: user == null ? void 0 : user.id
1197
- }
1198
- }).catch(e => {
1199
- toast.push({
1200
- status: "error",
1201
- title: "Generate image description failed",
1202
- description: e.message
1203
- });
1204
- setLoading(false);
1205
- throw e;
1206
- }).finally(() => {
1207
- setTimeout(() => {
1208
- setLoading(false);
1209
- }, 2e3);
1210
- });
1211
- }, [setLoading, apiClient, toast, user, types]);
1212
- return react.useMemo(() => ({
1213
- generateCaption,
1214
- loading
1215
- }), [generateCaption, loading]);
1216
- }
1217
- function useGenerateImage(apiClient) {
1218
- const [loading, setLoading] = react.useState(false);
1219
- const user = sanity.useCurrentUser();
1220
- const schema = sanity.useSchema();
1221
- const types = react.useMemo(() => serializeSchema(schema, {
1222
- leanFormat: true
1223
- }), [schema]);
1224
- const toast = ui.useToast();
1225
- const generateImage = react.useCallback(_ref6 => {
1226
- let {
1227
- path,
1228
- documentId
1229
- } = _ref6;
1230
- setLoading(true);
1231
- return apiClient.request({
1232
- method: "POST",
1233
- url: "/assist/tasks/generate-image/".concat(apiClient.config().dataset, "?projectId=").concat(apiClient.config().projectId),
1234
- body: {
1235
- path,
1236
- documentId,
1237
- types,
1238
- userId: user == null ? void 0 : user.id
1239
- }
1240
- }).catch(e => {
1241
- toast.push({
1242
- status: "error",
1243
- title: "Generate image from prompt failed",
1244
- description: e.message
1245
- });
1246
- setLoading(false);
1247
- throw e;
1248
- }).finally(() => {
1249
- setTimeout(() => {
1250
- setLoading(false);
1251
- }, 2e3);
1252
- });
1253
- }, [setLoading, apiClient, toast, user, types]);
1254
- return react.useMemo(() => ({
1255
- generateImage,
1256
- loading
1257
- }), [generateImage, loading]);
1258
- }
1259
- function useGetInstructStatus(apiClient) {
1260
- const [loading, setLoading] = react.useState(true);
1261
- const getInstructStatus = react.useCallback(async () => {
949
+ function useGetInstructStatus(apiClient) {
950
+ const [loading, setLoading] = react.useState(true);
951
+ const getInstructStatus = react.useCallback(async () => {
1262
952
  setLoading(true);
1263
953
  const projectId = apiClient.config().projectId;
1264
954
  try {
@@ -1383,345 +1073,62 @@ function AiAssistanceConfigProvider(props) {
1383
1073
  children
1384
1074
  });
1385
1075
  }
1386
- const NO_INPUT = {};
1387
- const RunInstructionContext = react.createContext({
1388
- runInstruction: () => {},
1389
- instructionLoading: false
1390
- });
1391
- function useRunInstruction() {
1392
- return react.useContext(RunInstructionContext);
1076
+ const aiDocPrefixPattern = new RegExp("^".concat(assistDocumentIdPrefix));
1077
+ function publicId(id) {
1078
+ return id.replace("drafts.", "");
1393
1079
  }
1394
- function isUserInputBlock(block) {
1395
- return block._type === userInputTypeName;
1080
+ function assistDocumentId(documentType) {
1081
+ return "".concat(assistDocumentIdPrefix).concat(documentType);
1396
1082
  }
1397
- function RunInstructionProvider(props) {
1398
- var _a;
1399
- const {
1400
- config
1401
- } = useAiAssistanceConfig();
1402
- const apiClient = useApiClient(config == null ? void 0 : config.__customApiClient);
1083
+ function documentTypeFromAiDocumentId(id) {
1084
+ return id.replace(aiDocPrefixPattern, "");
1085
+ }
1086
+ function assistTasksStatusId(documentId) {
1087
+ return "".concat(assistDocumentStatusIdPrefix).concat(publicId(documentId));
1088
+ }
1089
+ const aiInspectorId = "ai-assistance";
1090
+ function BackToInstructionListLink() {
1403
1091
  const {
1404
- runInstruction: runInstructionRequest,
1405
- loading
1406
- } = useRunInstructionApi(apiClient);
1407
- const id = react.useId();
1408
- const [inputs, setInputs] = react.useState(NO_INPUT);
1409
- const [runRequest, setRunRequest] = react.useState();
1410
- const runInstruction = react.useCallback(req => {
1411
- var _a2;
1412
- if (loading) {
1413
- return;
1414
- }
1415
- const {
1416
- instruction,
1417
- ...request
1418
- } = req;
1419
- const instructionKey = instruction._key;
1420
- const userInputBlocks = (_a2 = instruction == null ? void 0 : instruction.prompt) == null ? void 0 : _a2.flatMap(block => block._type === "block" ? block.children.filter(isUserInputBlock) : [block]).filter(isUserInputBlock);
1421
- if (!(userInputBlocks == null ? void 0 : userInputBlocks.length)) {
1422
- runInstructionRequest({
1423
- ...request,
1424
- instructionKey,
1425
- userTexts: void 0
1426
- });
1427
- return;
1428
- }
1429
- setRunRequest({
1430
- ...req,
1431
- userInputBlocks
1432
- });
1433
- }, [setRunRequest, runInstructionRequest, loading]);
1434
- const close = react.useCallback(() => {
1435
- setRunRequest(void 0);
1436
- setInputs(NO_INPUT);
1437
- }, [setRunRequest, setInputs]);
1438
- const runWithInput = react.useCallback(() => {
1439
- if (runRequest) {
1440
- const {
1441
- instruction,
1442
- userTexts,
1443
- ...request
1444
- } = runRequest;
1445
- runInstructionRequest({
1446
- ...request,
1447
- instructionKey: instruction._key,
1448
- userTexts: Object.entries(inputs).map(_ref7 => {
1449
- let [key, value] = _ref7;
1450
- return {
1451
- blockKey: key,
1452
- userInput: value
1453
- };
1454
- })
1455
- });
1456
- }
1457
- close();
1458
- }, [close, runInstructionRequest, runRequest, inputs]);
1459
- const open = !!runRequest;
1460
- const runDisabled = react.useMemo(() => {
1461
- var _a2, _b;
1462
- return ((_b = (_a2 = runRequest == null ? void 0 : runRequest.userInputBlocks) == null ? void 0 : _a2.length) != null ? _b : 0) > Object.entries(inputs).filter(_ref8 => {
1463
- let [, value] = _ref8;
1464
- return !!value;
1465
- }).length;
1466
- }, [runRequest == null ? void 0 : runRequest.userInputBlocks, inputs]);
1467
- const runButton = /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
1468
- text: "Run instruction",
1469
- onClick: runWithInput,
1470
- tone: "primary",
1471
- icon: icons.PlayIcon,
1472
- style: {
1473
- width: "100%"
1474
- },
1475
- disabled: runDisabled
1092
+ openInspector
1093
+ } = desk.useDocumentPane();
1094
+ const goBack = react.useCallback(() => openInspector(aiInspectorId, {
1095
+ [instructionParam]: void 0
1096
+ }), [openInspector]);
1097
+ return /* @__PURE__ */jsxRuntime.jsx("div", {
1098
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
1099
+ as: "a",
1100
+ fontSize: 1,
1101
+ icon: icons.ArrowLeftIcon,
1102
+ mode: "bleed",
1103
+ padding: 1,
1104
+ space: 2,
1105
+ onClick: goBack,
1106
+ text: " Instructions",
1107
+ textAlign: "left"
1108
+ })
1476
1109
  });
1477
- const contextValue = react.useMemo(() => ({
1478
- runInstruction,
1479
- instructionLoading: loading
1480
- }), [runInstruction, loading]);
1481
- return /* @__PURE__ */jsxRuntime.jsxs(RunInstructionContext.Provider, {
1482
- value: contextValue,
1483
- children: [open ? /* @__PURE__ */jsxRuntime.jsx(ui.Dialog, {
1484
- id,
1485
- open,
1486
- onClose: close,
1487
- width: 1,
1488
- header: getInstructionTitle(runRequest == null ? void 0 : runRequest.instruction),
1489
- footer: /* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
1490
- justify: "space-between",
1491
- padding: 2,
1492
- flex: 1,
1493
- children: runDisabled ? /* @__PURE__ */jsxRuntime.jsx(ui.Tooltip, {
1494
- content: /* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
1495
- padding: 2,
1496
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
1497
- children: "Unable to run instruction. All fields must have a value."
1498
- })
1499
- }),
1500
- placement: "top",
1501
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
1502
- flex: 1,
1503
- children: runButton
1504
- })
1505
- }) : runButton
1506
- }),
1507
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Stack, {
1508
- padding: 4,
1509
- space: 2,
1510
- children: (_a = runRequest == null ? void 0 : runRequest.userInputBlocks) == null ? void 0 : _a.map((block, i) => /* @__PURE__ */jsxRuntime.jsx(UserInput, {
1511
- block,
1512
- autoFocus: i === 0,
1513
- inputs,
1514
- setInputs
1515
- }, block._key))
1110
+ }
1111
+ const EMPTY_FIELDS = [];
1112
+ const TypePathContext = react.createContext(void 0);
1113
+ function AssistDocumentForm(props) {
1114
+ if (props.readOnly) {
1115
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
1116
+ border: true,
1117
+ tone: "caution",
1118
+ padding: 2,
1119
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
1120
+ size: 1,
1121
+ children: " You do not have sufficient permissions to manage instructions."
1516
1122
  })
1517
- }) : null, props.children]
1123
+ });
1124
+ }
1125
+ return /* @__PURE__ */jsxRuntime.jsx(AssistDocumentFormEditable, {
1126
+ ...props
1518
1127
  });
1519
1128
  }
1520
- function UserInput(props) {
1521
- var _a;
1129
+ function AssistDocumentFormEditable(props) {
1522
1130
  const {
1523
- block,
1524
- autoFocus,
1525
- setInputs,
1526
- inputs
1527
- } = props;
1528
- const key = block._key;
1529
- const textAreaRef = react.useRef(null);
1530
- const onChange = react.useCallback(e => {
1531
- setInputs(current => {
1532
- var _a2;
1533
- return {
1534
- ...current,
1535
- [key]: ((_a2 = e.currentTarget) != null ? _a2 : e.target).value
1536
- };
1537
- });
1538
- }, [key, setInputs]);
1539
- const value = react.useMemo(() => inputs[key], [inputs, key]);
1540
- react.useEffect(() => {
1541
- if (!autoFocus) {
1542
- return;
1543
- }
1544
- setTimeout(() => {
1545
- var _a2;
1546
- return (_a2 = textAreaRef.current) == null ? void 0 : _a2.focus();
1547
- }, 0);
1548
- }, [autoFocus]);
1549
- return /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
1550
- padding: 2,
1551
- space: 3,
1552
- children: [/* @__PURE__ */jsxRuntime.jsx(sanity.FormFieldHeaderText, {
1553
- title: (_a = block == null ? void 0 : block.message) != null ? _a : "Provide more context",
1554
- description: block.description
1555
- }), /* @__PURE__ */jsxRuntime.jsx(ui.TextArea, {
1556
- ref: textAreaRef,
1557
- rows: 4,
1558
- value,
1559
- onChange,
1560
- style: {
1561
- resize: "vertical"
1562
- }
1563
- })]
1564
- });
1565
- }
1566
- function isDocAssistable(documentSchemaType, published, draft) {
1567
- return !!(documentSchemaType.liveEdit ? published : draft);
1568
- }
1569
- function getAssistableDocId(documentSchemaType, documentId) {
1570
- const baseId = publicId(documentId);
1571
- return documentSchemaType.liveEdit ? baseId : "drafts.".concat(baseId);
1572
- }
1573
- function useRequestRunInstruction(args) {
1574
- const {
1575
- runInstruction,
1576
- instructionLoading
1577
- } = useRunInstruction();
1578
- const requestRunInstruction = useDraftDelayedTask({
1579
- ...args,
1580
- task: runInstruction
1581
- });
1582
- return {
1583
- instructionLoading,
1584
- requestRunInstruction
1585
- };
1586
- }
1587
- function useDraftDelayedTask(args) {
1588
- const {
1589
- documentOnChange,
1590
- isDocAssistable: isDocAssistable2,
1591
- task
1592
- } = args;
1593
- const [queuedArgs, setQueuedArgs] = react.useState(void 0);
1594
- react.useEffect(() => {
1595
- if (queuedArgs && isDocAssistable2) {
1596
- task(queuedArgs);
1597
- setQueuedArgs(void 0);
1598
- }
1599
- }, [queuedArgs, isDocAssistable2, task]);
1600
- return react.useCallback(taskArgs => {
1601
- documentOnChange(sanity.PatchEvent.from([sanity.unset(["_force_document_creation"])]));
1602
- setQueuedArgs(taskArgs);
1603
- }, [setQueuedArgs, documentOnChange]);
1604
- }
1605
- const SparklesIllustration = styled__default.default(icons.SparklesIcon)({
1606
- fontSize: "3.125em",
1607
- "& path": {
1608
- strokeWidth: "0.6px !important"
1609
- }
1610
- });
1611
- function InspectorOnboarding(props) {
1612
- const {
1613
- onDismiss
1614
- } = props;
1615
- return /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
1616
- padding: 4,
1617
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Container, {
1618
- width: 0,
1619
- children: /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
1620
- space: 4,
1621
- children: [/* @__PURE__ */jsxRuntime.jsx("div", {
1622
- style: {
1623
- textAlign: "center"
1624
- },
1625
- children: /* @__PURE__ */jsxRuntime.jsx(SparklesIllustration, {})
1626
- }), /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
1627
- align: "center",
1628
- size: 1,
1629
- children: "Create reusable AI instructions that can be applied across all documents of a certain type."
1630
- }), /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
1631
- align: "center",
1632
- gap: 2,
1633
- justify: "center",
1634
- children: [/* @__PURE__ */jsxRuntime.jsx(ui.Button, {
1635
- as: "a",
1636
- href: releaseAnnouncementUrl,
1637
- rel: "noreferrer",
1638
- target: "_blank",
1639
- fontSize: 1,
1640
- mode: "default",
1641
- onClick: onDismiss,
1642
- padding: 2,
1643
- text: "Learn more",
1644
- tone: "primary"
1645
- }), /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
1646
- fontSize: 1,
1647
- mode: "bleed",
1648
- onClick: onDismiss,
1649
- padding: 2,
1650
- text: "Dismiss"
1651
- })]
1652
- })]
1653
- })
1654
- })
1655
- });
1656
- }
1657
- const inspectorOnboardingKey = "sanityStudio:assist:inspector:onboarding:dismissed";
1658
- const fieldOnboardingKey = "sanityStudio:assist:field:onboarding:dismissed";
1659
- function isFeatureOnboardingDismissed(featureKey) {
1660
- if (typeof localStorage === "undefined") {
1661
- return false;
1662
- }
1663
- const value = localStorage.getItem(featureKey);
1664
- return value === "true";
1665
- }
1666
- function dismissFeatureOnboarding(featureKey) {
1667
- if (typeof localStorage === "undefined") {
1668
- return;
1669
- }
1670
- localStorage.setItem(featureKey, "true");
1671
- }
1672
- function useOnboardingFeature(featureKey) {
1673
- const [showOnboarding, setShowOnboarding] = react.useState(() => !isFeatureOnboardingDismissed(featureKey));
1674
- const dismissOnboarding = react.useCallback(() => {
1675
- setShowOnboarding(false);
1676
- dismissFeatureOnboarding(featureKey);
1677
- }, [setShowOnboarding, featureKey]);
1678
- return {
1679
- showOnboarding,
1680
- dismissOnboarding
1681
- };
1682
- }
1683
- function BackToInstructionListLink() {
1684
- const {
1685
- openInspector
1686
- } = desk.useDocumentPane();
1687
- const goBack = react.useCallback(() => openInspector(aiInspectorId, {
1688
- [instructionParam]: void 0
1689
- }), [openInspector]);
1690
- return /* @__PURE__ */jsxRuntime.jsx("div", {
1691
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
1692
- as: "a",
1693
- fontSize: 1,
1694
- icon: icons.ArrowLeftIcon,
1695
- mode: "bleed",
1696
- padding: 1,
1697
- space: 2,
1698
- onClick: goBack,
1699
- text: " Instructions",
1700
- textAlign: "left"
1701
- })
1702
- });
1703
- }
1704
- const EMPTY_FIELDS = [];
1705
- const TypePathContext = react.createContext(void 0);
1706
- function AssistDocumentForm(props) {
1707
- if (props.readOnly) {
1708
- return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
1709
- border: true,
1710
- tone: "caution",
1711
- padding: 2,
1712
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
1713
- size: 1,
1714
- children: " You do not have sufficient permissions to manage instructions."
1715
- })
1716
- });
1717
- }
1718
- return /* @__PURE__ */jsxRuntime.jsx(AssistDocumentFormEditable, {
1719
- ...props
1720
- });
1721
- }
1722
- function AssistDocumentFormEditable(props) {
1723
- const {
1724
- onChange
1131
+ onChange
1725
1132
  } = props;
1726
1133
  const value = props.value;
1727
1134
  const id = value == null ? void 0 : value._id;
@@ -1852,14 +1259,14 @@ function useSelectedSchema(fieldPath, documentSchema) {
1852
1259
  return currentSchema;
1853
1260
  }, [documentSchema, fieldPath]);
1854
1261
  }
1855
- function FieldsInitializer(_ref9) {
1262
+ function FieldsInitializer(_ref5) {
1856
1263
  let {
1857
1264
  pathKey,
1858
1265
  activePath,
1859
1266
  fields,
1860
1267
  documentSchema,
1861
1268
  onChange
1862
- } = _ref9;
1269
+ } = _ref5;
1863
1270
  const {
1864
1271
  config: {
1865
1272
  __presets: presets
@@ -1919,206 +1326,799 @@ function FieldsInitializer(_ref9) {
1919
1326
  }, [activePath, onChange, pathKey, existingField, missingPresetInstructions]);
1920
1327
  return null;
1921
1328
  }
1922
- function FieldAutocomplete(props) {
1923
- const {
1924
- id,
1329
+ function useDocumentState(id, docType) {
1330
+ const state = sanity.useEditState(id, docType);
1331
+ return state.draft || state.published;
1332
+ }
1333
+ function useStudioAssistDocument(_ref6) {
1334
+ let {
1335
+ documentId,
1925
1336
  schemaType,
1926
- fieldPath,
1927
- onSelect,
1928
- includeDocument,
1929
- filter
1930
- } = props;
1931
- const fieldRefs = react.useMemo(() => {
1932
- if (includeDocument) {
1933
- return getFieldRefsWithDocument(schemaType);
1934
- }
1935
- return getFieldRefs(schemaType);
1936
- }, [schemaType, includeDocument]);
1937
- const currentField = react.useMemo(() => fieldRefs.find(f => f.key === fieldPath), [fieldPath, fieldRefs]);
1938
- const autocompleteOptions = react.useMemo(() => fieldRefs.filter(field => filter ? filter(field) : true).filter(f => !isType(f.schemaType, "reference")).map(field => ({
1939
- value: field.key,
1940
- field
1941
- })), [fieldRefs, filter]);
1942
- const renderOption = react.useCallback(option => {
1943
- const {
1944
- value,
1945
- field
1946
- } = option;
1947
- if (!value) {
1948
- return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
1949
- as: "button",
1950
- padding: 3,
1951
- radius: 1,
1952
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
1953
- accent: true,
1954
- size: 1,
1955
- children: option.value
1956
- })
1957
- });
1337
+ initDoc
1338
+ } = _ref6;
1339
+ const documentTypeName = schemaType.name;
1340
+ const currentUser = sanity.useCurrentUser();
1341
+ const assistDocument = useDocumentState(assistDocumentId(documentTypeName), assistDocumentTypeName);
1342
+ const assistTasksStatus = useDocumentState(assistTasksStatusId(documentId != null ? documentId : ""), assistTasksStatusTypeName);
1343
+ const client = sanity.useClient({
1344
+ apiVersion: "2023-01-01"
1345
+ });
1346
+ react.useEffect(() => {
1347
+ if (!assistDocument && initDoc) {
1348
+ client.createIfNotExists({
1349
+ _id: assistDocumentId(documentTypeName),
1350
+ _type: assistDocumentTypeName
1351
+ }).catch(() => {});
1958
1352
  }
1959
- if (isType(field.schemaType, "document")) {
1960
- return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
1961
- as: "button",
1962
- padding: 3,
1963
- radius: 1,
1964
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
1965
- size: 1,
1966
- weight: "semibold",
1967
- children: "The entire document"
1968
- })
1969
- });
1353
+ }, [client, assistDocument, documentTypeName, initDoc]);
1354
+ return react.useMemo(() => {
1355
+ var _a, _b;
1356
+ if (!assistDocument) {
1357
+ return void 0;
1970
1358
  }
1971
- return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
1972
- as: "button",
1973
- padding: 3,
1974
- radius: 1,
1975
- children: /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
1976
- gap: 3,
1977
- children: [/* @__PURE__ */jsxRuntime.jsx(ui.Text, {
1978
- size: 1,
1979
- children: react.createElement(field.icon)
1980
- }), /* @__PURE__ */jsxRuntime.jsx(FieldTitle, {
1981
- field
1982
- })]
1983
- })
1359
+ const tasks = (_a = assistTasksStatus == null ? void 0 : assistTasksStatus.tasks) != null ? _a : [];
1360
+ const fields = ((_b = assistDocument == null ? void 0 : assistDocument.fields) != null ? _b : []).map(assistField => {
1361
+ var _a2;
1362
+ return {
1363
+ ...assistField,
1364
+ tasks: tasks.filter(task => task.path === assistField.path),
1365
+ 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))
1366
+ };
1984
1367
  });
1985
- }, []);
1986
- const renderValue = react.useCallback((value, option) => {
1987
- var _a;
1988
- return (_a = option == null ? void 0 : option.field.title) != null ? _a : value;
1989
- }, []);
1990
- const filterOption = react.useCallback((query, option) => {
1991
- var _a, _b, _c;
1992
- const lQuery = query.toLowerCase();
1993
- return ((_a = option == null ? void 0 : option.value) == null ? void 0 : _a.toLowerCase().includes(lQuery)) || ((_c = (_b = option == null ? void 0 : option.field) == null ? void 0 : _b.title) == null ? void 0 : _c.toLowerCase().includes(lQuery));
1994
- }, []);
1995
- return /* @__PURE__ */jsxRuntime.jsx(ui.Autocomplete, {
1996
- fontSize: 1,
1997
- icon: currentField ? currentField.icon : icons.SearchIcon,
1998
- onChange: onSelect,
1999
- openButton: true,
2000
- id,
2001
- options: autocompleteOptions,
2002
- placeholder: "Search for a field",
2003
- radius: 2,
2004
- renderOption,
2005
- renderValue,
2006
- value: currentField == null ? void 0 : currentField.key,
2007
- filterOption
2008
- });
2009
- }
2010
- function FieldTitle(props) {
2011
- const splitTitle = props.field.title.split("/");
2012
- return /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
2013
- flex: "none",
2014
- children: /* @__PURE__ */jsxRuntime.jsxs(ui.Breadcrumbs, {
2015
- style: {
2016
- display: "flex",
2017
- flexWrap: "wrap",
2018
- alignItems: "center",
2019
- marginTop: "-4px"
2020
- },
2021
- separator: /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
2022
- marginTop: 1,
2023
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
2024
- muted: true,
2025
- size: 1,
2026
- children: "/"
2027
- })
1368
+ return sanity.typed({
1369
+ ...assistDocument,
1370
+ tasks: tasks == null ? void 0 : tasks.map(task => {
1371
+ var _a2, _b2;
1372
+ const instruction = (_b2 = (_a2 = fields.find(f => f.path === task.path)) == null ? void 0 : _a2.instructions) == null ? void 0 : _b2.find(i => i._key === task.instructionKey);
1373
+ return {
1374
+ ...task,
1375
+ instruction
1376
+ };
2028
1377
  }),
2029
- space: 1,
2030
- children: [splitTitle.slice(0, splitTitle.length - 1).map((pt, i) =>
2031
- // eslint-disable-next-line react/no-array-index-key
2032
- /* @__PURE__ */
2033
- jsxRuntime.jsx(ui.Box, {
2034
- marginTop: 1,
2035
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
2036
- muted: true,
2037
- size: 1,
2038
- children: pt.trim()
2039
- })
2040
- }, i)), /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
2041
- marginTop: 1,
2042
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
2043
- size: 1,
2044
- weight: "medium",
2045
- children: splitTitle[splitTitle.length - 1]
2046
- })
2047
- })]
2048
- })
2049
- });
2050
- }
2051
- const MAX_DEPTH = 8;
2052
- function getConditionalMembers(docState) {
2053
- const doc = {
2054
- path: "",
2055
- hidden: false,
2056
- readOnly: !!docState.readOnly,
2057
- conditional: typeof docState.schemaType.hidden === "function"
2058
- };
2059
- return [doc, ...extractConditionalPaths(docState, MAX_DEPTH)].filter(v => v.conditional).map(_ref10 => {
2060
- let {
2061
- conditional,
2062
- ...state
2063
- } = _ref10;
2064
- return {
2065
- ...state
2066
- };
2067
- });
2068
- }
2069
- function isConditional(schemaType) {
2070
- return typeof schemaType.hidden === "function" || typeof schemaType.readOnly === "function";
1378
+ fields
1379
+ });
1380
+ }, [assistDocument, assistTasksStatus, currentUser]);
2071
1381
  }
2072
- function conditionalState(memberState) {
1382
+ function asStudioInstruction(instruction, run) {
2073
1383
  return {
2074
- path: sanity.pathToString(memberState.path),
2075
- readOnly: !!memberState.readOnly,
2076
- hidden: false,
2077
- // if its in members, its not hidden
2078
- conditional: isConditional(memberState.schemaType)
1384
+ ...instruction,
1385
+ tasks: run.filter(task => task.instructionKey === instruction._key).filter(task => task.started && ( /* @__PURE__ */new Date()).getTime() - new Date(task.started).getTime() < maxHistoryVisibilityMs)
2079
1386
  };
2080
1387
  }
2081
- function extractConditionalPaths(node, maxDepth) {
2082
- if (node.path.length >= maxDepth) {
2083
- return [];
1388
+ function usePathKey(path) {
1389
+ return react.useMemo(() => {
1390
+ return getPathKey(path);
1391
+ }, [path]);
1392
+ }
1393
+ function getPathKey(path) {
1394
+ if (path.length) {
1395
+ return Array.isArray(path) ? sanity.pathToString(path) : path;
2084
1396
  }
2085
- return node.members.reduce((acc, member) => {
2086
- var _a, _b;
2087
- if (member.kind === "error") {
2088
- return acc;
1397
+ return documentRootKey;
1398
+ }
1399
+ function getInstructionTitle(instruction) {
1400
+ var _a;
1401
+ return (_a = instruction == null ? void 0 : instruction.title) != null ? _a : "Untitled";
1402
+ }
1403
+ const NO_INPUT = {};
1404
+ const RunInstructionContext = react.createContext({
1405
+ runInstruction: () => {},
1406
+ instructionLoading: false
1407
+ });
1408
+ function useRunInstruction() {
1409
+ return react.useContext(RunInstructionContext);
1410
+ }
1411
+ function isUserInputBlock(block) {
1412
+ return block._type === userInputTypeName;
1413
+ }
1414
+ function RunInstructionProvider(props) {
1415
+ var _a;
1416
+ const {
1417
+ config
1418
+ } = useAiAssistanceConfig();
1419
+ const apiClient = useApiClient(config == null ? void 0 : config.__customApiClient);
1420
+ const {
1421
+ runInstruction: runInstructionRequest,
1422
+ loading
1423
+ } = useRunInstructionApi(apiClient);
1424
+ const id = react.useId();
1425
+ const [inputs, setInputs] = react.useState(NO_INPUT);
1426
+ const [runRequest, setRunRequest] = react.useState();
1427
+ const runInstruction = react.useCallback(req => {
1428
+ var _a2;
1429
+ if (loading) {
1430
+ return;
2089
1431
  }
2090
- if (member.kind === "field") {
2091
- const schemaType = member.field.schemaType;
2092
- if (schemaType.jsonType === "object") {
2093
- const innerFields = member.field.readOnly ? [] : extractConditionalPaths(member.field, maxDepth);
2094
- return [...acc, conditionalState(member.field), ...innerFields];
2095
- } else if (schemaType.jsonType === "array") {
2096
- const array = member.field;
2097
- let arrayPaths = [];
2098
- const isObjectsArray = array.members.some(m => m.kind === "item" && sanity.isObjectSchemaType(m.item.schemaType));
2099
- if (!array.readOnly) {
2100
- for (const arrayMember of array.members) {
2101
- if (arrayMember.kind === "error") {
2102
- continue;
2103
- }
2104
- const innerFields = isObjectsArray && !arrayMember.item.readOnly ? extractConditionalPaths(arrayMember.item, maxDepth) : [];
2105
- arrayPaths = [...arrayPaths, conditionalState(arrayMember.item), ...innerFields];
2106
- }
2107
- }
2108
- return [...acc, conditionalState(array), ...arrayPaths];
2109
- }
2110
- return [...acc, conditionalState(member.field)];
2111
- } else if (member.kind === "fieldSet") {
2112
- 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"));
2113
- const innerFields = extractConditionalPaths(member.fieldSet, maxDepth).map(f => ({
2114
- ...f,
2115
- // if fieldset is conditional, visible fields must also be considered conditional
2116
- conditional: conditionalFieldset != null ? conditionalFieldset : f.conditional
2117
- }));
2118
- return [...acc, ...innerFields];
1432
+ const {
1433
+ instruction,
1434
+ ...request
1435
+ } = req;
1436
+ const instructionKey = instruction._key;
1437
+ const userInputBlocks = (_a2 = instruction == null ? void 0 : instruction.prompt) == null ? void 0 : _a2.flatMap(block => block._type === "block" ? block.children.filter(isUserInputBlock) : [block]).filter(isUserInputBlock);
1438
+ if (!(userInputBlocks == null ? void 0 : userInputBlocks.length)) {
1439
+ runInstructionRequest({
1440
+ ...request,
1441
+ instructionKey,
1442
+ userTexts: void 0
1443
+ });
1444
+ return;
2119
1445
  }
2120
- return acc;
1446
+ setRunRequest({
1447
+ ...req,
1448
+ userInputBlocks
1449
+ });
1450
+ }, [runInstructionRequest, loading]);
1451
+ const close = react.useCallback(() => {
1452
+ setRunRequest(void 0);
1453
+ setInputs(NO_INPUT);
2121
1454
  }, []);
1455
+ const runWithInput = react.useCallback(() => {
1456
+ if (runRequest) {
1457
+ const {
1458
+ instruction,
1459
+ userTexts,
1460
+ ...request
1461
+ } = runRequest;
1462
+ runInstructionRequest({
1463
+ ...request,
1464
+ instructionKey: instruction._key,
1465
+ userTexts: Object.entries(inputs).map(_ref7 => {
1466
+ let [key, value] = _ref7;
1467
+ return {
1468
+ blockKey: key,
1469
+ userInput: value
1470
+ };
1471
+ })
1472
+ });
1473
+ }
1474
+ close();
1475
+ }, [close, runInstructionRequest, runRequest, inputs]);
1476
+ const open = !!runRequest;
1477
+ const runDisabled = react.useMemo(() => {
1478
+ var _a2, _b;
1479
+ return ((_b = (_a2 = runRequest == null ? void 0 : runRequest.userInputBlocks) == null ? void 0 : _a2.length) != null ? _b : 0) > Object.entries(inputs).filter(_ref8 => {
1480
+ let [, value] = _ref8;
1481
+ return !!value;
1482
+ }).length;
1483
+ }, [runRequest == null ? void 0 : runRequest.userInputBlocks, inputs]);
1484
+ const runButton = /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
1485
+ text: "Run instruction",
1486
+ onClick: runWithInput,
1487
+ tone: "primary",
1488
+ icon: icons.PlayIcon,
1489
+ style: {
1490
+ width: "100%"
1491
+ },
1492
+ disabled: runDisabled
1493
+ });
1494
+ const contextValue = react.useMemo(() => ({
1495
+ runInstruction,
1496
+ instructionLoading: loading
1497
+ }), [runInstruction, loading]);
1498
+ return /* @__PURE__ */jsxRuntime.jsxs(RunInstructionContext.Provider, {
1499
+ value: contextValue,
1500
+ children: [open ? /* @__PURE__ */jsxRuntime.jsx(ui.Dialog, {
1501
+ id,
1502
+ open,
1503
+ onClose: close,
1504
+ width: 1,
1505
+ header: getInstructionTitle(runRequest == null ? void 0 : runRequest.instruction),
1506
+ footer: /* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
1507
+ justify: "space-between",
1508
+ padding: 2,
1509
+ flex: 1,
1510
+ children: runDisabled ? /* @__PURE__ */jsxRuntime.jsx(ui.Tooltip, {
1511
+ content: /* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
1512
+ padding: 2,
1513
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
1514
+ children: "Unable to run instruction. All fields must have a value."
1515
+ })
1516
+ }),
1517
+ placement: "top",
1518
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
1519
+ flex: 1,
1520
+ children: runButton
1521
+ })
1522
+ }) : runButton
1523
+ }),
1524
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Stack, {
1525
+ padding: 4,
1526
+ space: 2,
1527
+ children: (_a = runRequest == null ? void 0 : runRequest.userInputBlocks) == null ? void 0 : _a.map((block, i) => /* @__PURE__ */jsxRuntime.jsx(UserInput, {
1528
+ block,
1529
+ autoFocus: i === 0,
1530
+ inputs,
1531
+ setInputs
1532
+ }, block._key))
1533
+ })
1534
+ }) : null, props.children]
1535
+ });
1536
+ }
1537
+ function UserInput(props) {
1538
+ var _a;
1539
+ const {
1540
+ block,
1541
+ autoFocus,
1542
+ setInputs,
1543
+ inputs
1544
+ } = props;
1545
+ const key = block._key;
1546
+ const textAreaRef = react.useRef(null);
1547
+ const onChange = react.useCallback(e => {
1548
+ setInputs(current => {
1549
+ var _a2;
1550
+ return {
1551
+ ...current,
1552
+ [key]: ((_a2 = e.currentTarget) != null ? _a2 : e.target).value
1553
+ };
1554
+ });
1555
+ }, [key, setInputs]);
1556
+ const value = react.useMemo(() => inputs[key], [inputs, key]);
1557
+ react.useEffect(() => {
1558
+ if (!autoFocus) {
1559
+ return;
1560
+ }
1561
+ setTimeout(() => {
1562
+ var _a2;
1563
+ return (_a2 = textAreaRef.current) == null ? void 0 : _a2.focus();
1564
+ }, 0);
1565
+ }, [autoFocus]);
1566
+ return /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
1567
+ padding: 2,
1568
+ space: 3,
1569
+ children: [/* @__PURE__ */jsxRuntime.jsx(sanity.FormFieldHeaderText, {
1570
+ title: (_a = block == null ? void 0 : block.message) != null ? _a : "Provide more context",
1571
+ description: block.description
1572
+ }), /* @__PURE__ */jsxRuntime.jsx(ui.TextArea, {
1573
+ ref: textAreaRef,
1574
+ rows: 4,
1575
+ value,
1576
+ onChange,
1577
+ style: {
1578
+ resize: "vertical"
1579
+ }
1580
+ })]
1581
+ });
1582
+ }
1583
+ function isDocAssistable(documentSchemaType, published, draft) {
1584
+ return !!(documentSchemaType.liveEdit ? published : draft);
1585
+ }
1586
+ function getAssistableDocId(documentSchemaType, documentId) {
1587
+ const baseId = publicId(documentId);
1588
+ return documentSchemaType.liveEdit ? baseId : "drafts.".concat(baseId);
1589
+ }
1590
+ function useRequestRunInstruction(args) {
1591
+ const {
1592
+ runInstruction,
1593
+ instructionLoading
1594
+ } = useRunInstruction();
1595
+ const requestRunInstruction = useDraftDelayedTask({
1596
+ ...args,
1597
+ task: runInstruction
1598
+ });
1599
+ return {
1600
+ instructionLoading,
1601
+ requestRunInstruction
1602
+ };
1603
+ }
1604
+ function useDraftDelayedTask(args) {
1605
+ const {
1606
+ documentOnChange,
1607
+ isDocAssistable: isDocAssistable2,
1608
+ task
1609
+ } = args;
1610
+ const [queuedArgs, setQueuedArgs] = react.useState(void 0);
1611
+ react.useEffect(() => {
1612
+ if (queuedArgs && isDocAssistable2) {
1613
+ task(queuedArgs);
1614
+ setQueuedArgs(void 0);
1615
+ }
1616
+ }, [queuedArgs, isDocAssistable2, task]);
1617
+ return react.useCallback(taskArgs => {
1618
+ documentOnChange(sanity.PatchEvent.from([sanity.unset(["_force_document_creation"])]));
1619
+ setQueuedArgs(taskArgs);
1620
+ }, [setQueuedArgs, documentOnChange]);
1621
+ }
1622
+ const MAX_DEPTH = 8;
1623
+ function getConditionalMembers(docState) {
1624
+ const doc = {
1625
+ path: "",
1626
+ hidden: false,
1627
+ readOnly: !!docState.readOnly,
1628
+ conditional: typeof docState.schemaType.hidden === "function"
1629
+ };
1630
+ return [doc, ...extractConditionalPaths(docState, MAX_DEPTH)].filter(v => v.conditional).map(_ref9 => {
1631
+ let {
1632
+ conditional,
1633
+ ...state
1634
+ } = _ref9;
1635
+ return {
1636
+ ...state
1637
+ };
1638
+ });
1639
+ }
1640
+ function isConditional(schemaType) {
1641
+ return typeof schemaType.hidden === "function" || typeof schemaType.readOnly === "function";
1642
+ }
1643
+ function conditionalState(memberState) {
1644
+ return {
1645
+ path: sanity.pathToString(memberState.path),
1646
+ readOnly: !!memberState.readOnly,
1647
+ hidden: false,
1648
+ // if its in members, its not hidden
1649
+ conditional: isConditional(memberState.schemaType)
1650
+ };
1651
+ }
1652
+ function extractConditionalPaths(node, maxDepth) {
1653
+ if (node.path.length >= maxDepth) {
1654
+ return [];
1655
+ }
1656
+ return node.members.reduce((acc, member) => {
1657
+ var _a, _b;
1658
+ if (member.kind === "error") {
1659
+ return acc;
1660
+ }
1661
+ if (member.kind === "field") {
1662
+ const schemaType = member.field.schemaType;
1663
+ if (schemaType.jsonType === "object") {
1664
+ const innerFields = member.field.readOnly ? [] : extractConditionalPaths(member.field, maxDepth);
1665
+ return [...acc, conditionalState(member.field), ...innerFields];
1666
+ } else if (schemaType.jsonType === "array") {
1667
+ const array = member.field;
1668
+ let arrayPaths = [];
1669
+ const isObjectsArray = array.members.some(m => m.kind === "item" && sanity.isObjectSchemaType(m.item.schemaType));
1670
+ if (!array.readOnly) {
1671
+ for (const arrayMember of array.members) {
1672
+ if (arrayMember.kind === "error") {
1673
+ continue;
1674
+ }
1675
+ const innerFields = isObjectsArray && !arrayMember.item.readOnly ? extractConditionalPaths(arrayMember.item, maxDepth) : [];
1676
+ arrayPaths = [...arrayPaths, conditionalState(arrayMember.item), ...innerFields];
1677
+ }
1678
+ }
1679
+ return [...acc, conditionalState(array), ...arrayPaths];
1680
+ }
1681
+ return [...acc, conditionalState(member.field)];
1682
+ } else if (member.kind === "fieldSet") {
1683
+ 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"));
1684
+ const innerFields = extractConditionalPaths(member.fieldSet, maxDepth).map(f => ({
1685
+ ...f,
1686
+ // if fieldset is conditional, visible fields must also be considered conditional
1687
+ conditional: conditionalFieldset != null ? conditionalFieldset : f.conditional
1688
+ }));
1689
+ return [...acc, ...innerFields];
1690
+ }
1691
+ return acc;
1692
+ }, []);
1693
+ }
1694
+ const SparklesIllustration = styled__default.default(icons.SparklesIcon)({
1695
+ fontSize: "3.125em",
1696
+ "& path": {
1697
+ strokeWidth: "0.6px !important"
1698
+ }
1699
+ });
1700
+ function InspectorOnboarding(props) {
1701
+ const {
1702
+ onDismiss
1703
+ } = props;
1704
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
1705
+ padding: 4,
1706
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Container, {
1707
+ width: 0,
1708
+ children: /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
1709
+ space: 4,
1710
+ children: [/* @__PURE__ */jsxRuntime.jsx("div", {
1711
+ style: {
1712
+ textAlign: "center"
1713
+ },
1714
+ children: /* @__PURE__ */jsxRuntime.jsx(SparklesIllustration, {})
1715
+ }), /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
1716
+ align: "center",
1717
+ size: 1,
1718
+ children: "Create reusable AI instructions that can be applied across all documents of a certain type."
1719
+ }), /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
1720
+ align: "center",
1721
+ gap: 2,
1722
+ justify: "center",
1723
+ children: [/* @__PURE__ */jsxRuntime.jsx(ui.Button, {
1724
+ as: "a",
1725
+ href: releaseAnnouncementUrl,
1726
+ rel: "noreferrer",
1727
+ target: "_blank",
1728
+ fontSize: 1,
1729
+ mode: "default",
1730
+ onClick: onDismiss,
1731
+ padding: 2,
1732
+ text: "Learn more",
1733
+ tone: "primary"
1734
+ }), /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
1735
+ fontSize: 1,
1736
+ mode: "bleed",
1737
+ onClick: onDismiss,
1738
+ padding: 2,
1739
+ text: "Dismiss"
1740
+ })]
1741
+ })]
1742
+ })
1743
+ })
1744
+ });
1745
+ }
1746
+ const inspectorOnboardingKey = "sanityStudio:assist:inspector:onboarding:dismissed";
1747
+ const fieldOnboardingKey = "sanityStudio:assist:field:onboarding:dismissed";
1748
+ function isFeatureOnboardingDismissed(featureKey) {
1749
+ if (typeof localStorage === "undefined") {
1750
+ return false;
1751
+ }
1752
+ const value = localStorage.getItem(featureKey);
1753
+ return value === "true";
1754
+ }
1755
+ function dismissFeatureOnboarding(featureKey) {
1756
+ if (typeof localStorage === "undefined") {
1757
+ return;
1758
+ }
1759
+ localStorage.setItem(featureKey, "true");
1760
+ }
1761
+ function useOnboardingFeature(featureKey) {
1762
+ const [showOnboarding, setShowOnboarding] = react.useState(() => !isFeatureOnboardingDismissed(featureKey));
1763
+ const dismissOnboarding = react.useCallback(() => {
1764
+ setShowOnboarding(false);
1765
+ dismissFeatureOnboarding(featureKey);
1766
+ }, [setShowOnboarding, featureKey]);
1767
+ return {
1768
+ showOnboarding,
1769
+ dismissOnboarding
1770
+ };
1771
+ }
1772
+ function FieldAutocomplete(props) {
1773
+ const {
1774
+ id,
1775
+ schemaType,
1776
+ fieldPath,
1777
+ onSelect,
1778
+ includeDocument,
1779
+ filter
1780
+ } = props;
1781
+ const fieldRefs = react.useMemo(() => {
1782
+ if (includeDocument) {
1783
+ return getFieldRefsWithDocument(schemaType);
1784
+ }
1785
+ return getFieldRefs(schemaType);
1786
+ }, [schemaType, includeDocument]);
1787
+ const currentField = react.useMemo(() => fieldRefs.find(f => f.key === fieldPath), [fieldPath, fieldRefs]);
1788
+ const autocompleteOptions = react.useMemo(() => fieldRefs.filter(field => filter ? filter(field) : true).filter(f => !isType(f.schemaType, "reference")).map(field => ({
1789
+ value: field.key,
1790
+ field
1791
+ })), [fieldRefs, filter]);
1792
+ const renderOption = react.useCallback(option => {
1793
+ const {
1794
+ value,
1795
+ field
1796
+ } = option;
1797
+ if (!value) {
1798
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
1799
+ as: "button",
1800
+ padding: 3,
1801
+ radius: 1,
1802
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
1803
+ accent: true,
1804
+ size: 1,
1805
+ children: option.value
1806
+ })
1807
+ });
1808
+ }
1809
+ if (isType(field.schemaType, "document")) {
1810
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
1811
+ as: "button",
1812
+ padding: 3,
1813
+ radius: 1,
1814
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
1815
+ size: 1,
1816
+ weight: "semibold",
1817
+ children: "The entire document"
1818
+ })
1819
+ });
1820
+ }
1821
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
1822
+ as: "button",
1823
+ padding: 3,
1824
+ radius: 1,
1825
+ children: /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
1826
+ gap: 3,
1827
+ children: [/* @__PURE__ */jsxRuntime.jsx(ui.Text, {
1828
+ size: 1,
1829
+ children: react.createElement(field.icon)
1830
+ }), /* @__PURE__ */jsxRuntime.jsx(FieldTitle, {
1831
+ field
1832
+ })]
1833
+ })
1834
+ });
1835
+ }, []);
1836
+ const renderValue = react.useCallback((value, option) => {
1837
+ var _a;
1838
+ return (_a = option == null ? void 0 : option.field.title) != null ? _a : value;
1839
+ }, []);
1840
+ const filterOption = react.useCallback((query, option) => {
1841
+ var _a, _b, _c;
1842
+ const lQuery = query.toLowerCase();
1843
+ return ((_a = option == null ? void 0 : option.value) == null ? void 0 : _a.toLowerCase().includes(lQuery)) || ((_c = (_b = option == null ? void 0 : option.field) == null ? void 0 : _b.title) == null ? void 0 : _c.toLowerCase().includes(lQuery));
1844
+ }, []);
1845
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Autocomplete, {
1846
+ fontSize: 1,
1847
+ icon: currentField ? currentField.icon : icons.SearchIcon,
1848
+ onChange: onSelect,
1849
+ openButton: true,
1850
+ id,
1851
+ options: autocompleteOptions,
1852
+ placeholder: "Search for a field",
1853
+ radius: 2,
1854
+ renderOption,
1855
+ renderValue,
1856
+ value: currentField == null ? void 0 : currentField.key,
1857
+ filterOption
1858
+ });
1859
+ }
1860
+ function FieldTitle(props) {
1861
+ const splitTitle = props.field.title.split("/");
1862
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
1863
+ flex: "none",
1864
+ children: /* @__PURE__ */jsxRuntime.jsxs(ui.Breadcrumbs, {
1865
+ style: {
1866
+ display: "flex",
1867
+ flexWrap: "wrap",
1868
+ alignItems: "center",
1869
+ marginTop: "-4px"
1870
+ },
1871
+ separator: /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
1872
+ marginTop: 1,
1873
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
1874
+ muted: true,
1875
+ size: 1,
1876
+ children: "/"
1877
+ })
1878
+ }),
1879
+ space: 1,
1880
+ children: [splitTitle.slice(0, splitTitle.length - 1).map((pt, i) =>
1881
+ // eslint-disable-next-line react/no-array-index-key
1882
+ /* @__PURE__ */
1883
+ jsxRuntime.jsx(ui.Box, {
1884
+ marginTop: 1,
1885
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
1886
+ muted: true,
1887
+ size: 1,
1888
+ children: pt.trim()
1889
+ })
1890
+ }, i)), /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
1891
+ marginTop: 1,
1892
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
1893
+ size: 1,
1894
+ weight: "medium",
1895
+ children: splitTitle[splitTitle.length - 1]
1896
+ })
1897
+ })]
1898
+ })
1899
+ });
1900
+ }
1901
+ function useInterval(ms) {
1902
+ const [tick, update] = react.useReducer(n => n + 1, 0);
1903
+ react.useEffect(() => {
1904
+ const i = setInterval(update, ms);
1905
+ return () => clearInterval(i);
1906
+ }, [ms]);
1907
+ return tick;
1908
+ }
1909
+ function TimeAgo(_ref10) {
1910
+ let {
1911
+ date
1912
+ } = _ref10;
1913
+ useInterval(1e3);
1914
+ const timeSince = formatDistanceToNow__default.default(date ? new Date(date) : /* @__PURE__ */new Date());
1915
+ return /* @__PURE__ */jsxRuntime.jsxs("span", {
1916
+ title: timeSince,
1917
+ children: [timeSince, " ago"]
1918
+ });
1919
+ }
1920
+ var __freeze$5 = Object.freeze;
1921
+ var __defProp$5 = Object.defineProperty;
1922
+ var __template$5 = (cooked, raw) => __freeze$5(__defProp$5(cooked, "raw", {
1923
+ value: __freeze$5(raw || cooked.slice())
1924
+ }));
1925
+ var _a$5, _b$3;
1926
+ const rotate = styled.keyframes(_a$5 || (_a$5 = __template$5(["\n 0% {\n transform: rotate(0);\n }\n 100% {\n transform: rotate(360deg);\n }\n"])));
1927
+ const SyncSpinningIcon = styled__default.default(icons.SyncIcon)(_b$3 || (_b$3 = __template$5(["\n animation: ", " 1s linear infinite;\n"])), rotate);
1928
+ const TASK_CONFIG = {
1929
+ aborted: {
1930
+ title: "Canceled",
1931
+ icon: icons.CloseCircleIcon,
1932
+ tone: "transparent"
1933
+ },
1934
+ error: {
1935
+ title: "Error",
1936
+ icon: icons.ErrorOutlineIcon,
1937
+ tone: "critical"
1938
+ },
1939
+ success: {
1940
+ title: "Completed",
1941
+ icon: icons.CheckmarkCircleIcon,
1942
+ tone: "positive"
1943
+ },
1944
+ timeout: {
1945
+ title: "Timeout",
1946
+ icon: icons.ClockIcon,
1947
+ tone: "caution"
1948
+ }
1949
+ };
1950
+ function InstructionTaskHistoryButton(props) {
1951
+ const {
1952
+ tasks,
1953
+ instructions,
1954
+ documentId,
1955
+ showTitles
1956
+ } = props;
1957
+ const client = sanity.useClient({
1958
+ apiVersion: "2023-01-01"
1959
+ });
1960
+ const cancelRun = react.useCallback(taskKey => {
1961
+ if (!documentId) {
1962
+ return;
1963
+ }
1964
+ const statusDocId = assistTasksStatusId(documentId);
1965
+ const basePath = "".concat(sanity.typed("tasks"), '[_key=="').concat(taskKey, '"]');
1966
+ client.patch(statusDocId).set({
1967
+ ["".concat(basePath, ".").concat(sanity.typed("ended"))]: ( /* @__PURE__ */new Date()).toISOString(),
1968
+ ["".concat(basePath, ".").concat(sanity.typed("reason"))]: sanity.typed("aborted")
1969
+ }).commit().catch(console.error);
1970
+ }, [client, documentId]);
1971
+ const titledTasks = react.useMemo(() => {
1972
+ var _a2;
1973
+ const t = (_a2 = tasks == null ? void 0 : tasks.filter(task => task.started && ( /* @__PURE__ */new Date()).getTime() - new Date(task.started).getTime() < maxHistoryVisibilityMs).map(task => {
1974
+ var _a3;
1975
+ const instruction = instructions == null ? void 0 : instructions.find(i => i._key === task.instructionKey);
1976
+ return {
1977
+ ...task,
1978
+ title: showTitles ? (_a3 = task.title) != null ? _a3 : getInstructionTitle(instruction) : void 0,
1979
+ cancel: () => cancelRun(task._key)
1980
+ };
1981
+ })) != null ? _a2 : [];
1982
+ t.sort((a, b) => {
1983
+ var _a3, _b2;
1984
+ return new Date((_a3 = b.started) != null ? _a3 : "").getTime() - new Date((_b2 = a.started) != null ? _b2 : "").getTime();
1985
+ });
1986
+ return t;
1987
+ }, [tasks, instructions, cancelRun, showTitles]);
1988
+ const isRunning = react.useMemo(() => titledTasks.some(r => !r.ended), [titledTasks]);
1989
+ const hasErrors = react.useMemo(() => titledTasks.some(r => r.reason === "error" || r.reason === "timeout"), [titledTasks]);
1990
+ const [open, setOpen] = react.useState(false);
1991
+ const toggleOpen = react.useCallback(() => setOpen(v => !v), []);
1992
+ const [button, setButton] = react.useState(null);
1993
+ const [popover, setPopover] = react.useState(null);
1994
+ const handleClickOutside = react.useCallback(() => {
1995
+ setOpen(false);
1996
+ }, []);
1997
+ ui.useClickOutside(handleClickOutside, [button, popover]);
1998
+ const handleEscape = react.useCallback(() => {
1999
+ setOpen(false);
2000
+ button == null ? void 0 : button.focus();
2001
+ }, [button]);
2002
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Popover, {
2003
+ constrainSize: true,
2004
+ content: /* @__PURE__ */jsxRuntime.jsx(TaskList, {
2005
+ onEscape: handleEscape,
2006
+ tasks: titledTasks
2007
+ }),
2008
+ open: open && !!(titledTasks == null ? void 0 : titledTasks.length),
2009
+ placement: "top",
2010
+ portal: true,
2011
+ ref: setPopover,
2012
+ width: 0,
2013
+ children: /* @__PURE__ */jsxRuntime.jsx(TaskStatusButton, {
2014
+ disabled: !(titledTasks == null ? void 0 : titledTasks.length),
2015
+ hasErrors,
2016
+ isRunning,
2017
+ onClick: toggleOpen,
2018
+ ref: setButton,
2019
+ selected: open
2020
+ })
2021
+ });
2022
+ }
2023
+ const TASK_STATUS_BUTTON_TOOLTIP_PROPS = {
2024
+ placement: "top"
2025
+ };
2026
+ const TaskStatusButton = react.forwardRef(function TaskStatusButton2(props, ref) {
2027
+ const {
2028
+ disabled,
2029
+ hasErrors,
2030
+ isRunning,
2031
+ onClick,
2032
+ selected
2033
+ } = props;
2034
+ return /* @__PURE__ */jsxRuntime.jsx(sanity.StatusButton, {
2035
+ label: "".concat(pluginTitle, " status"),
2036
+ icon: isRunning ? SyncSpinningIcon : hasErrors ? icons.ErrorOutlineIcon : icons.CheckmarkCircleIcon,
2037
+ mode: "bleed",
2038
+ onClick,
2039
+ tone: hasErrors ? "critical" : void 0,
2040
+ disabled,
2041
+ ref,
2042
+ selected,
2043
+ tooltipProps: TASK_STATUS_BUTTON_TOOLTIP_PROPS
2044
+ });
2045
+ });
2046
+ function TaskList(props) {
2047
+ const {
2048
+ onEscape,
2049
+ tasks
2050
+ } = props;
2051
+ const {
2052
+ isTopLayer
2053
+ } = ui.useLayer();
2054
+ ui.useGlobalKeyDown(react.useCallback(event => {
2055
+ if (isTopLayer && event.key === "Escape") {
2056
+ onEscape();
2057
+ }
2058
+ }, [isTopLayer, onEscape]));
2059
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Stack, {
2060
+ padding: 1,
2061
+ space: 1,
2062
+ children: tasks.map(task => /* @__PURE__ */jsxRuntime.jsx(TaskItem, {
2063
+ task
2064
+ }, task._key))
2065
+ });
2066
+ }
2067
+ function TaskItem(props) {
2068
+ var _a2;
2069
+ const {
2070
+ task
2071
+ } = props;
2072
+ const taskType = task.reason && TASK_CONFIG[task.reason];
2073
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
2074
+ radius: 2,
2075
+ tone: taskType && (taskType == null ? void 0 : taskType.tone),
2076
+ children: /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
2077
+ align: "center",
2078
+ gap: 1,
2079
+ children: [/* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
2080
+ align: "flex-start",
2081
+ flex: 1,
2082
+ gap: 3,
2083
+ padding: 3,
2084
+ children: [/* @__PURE__ */jsxRuntime.jsx(ui.Box, {
2085
+ flex: "none",
2086
+ children: /* @__PURE__ */jsxRuntime.jsxs(ui.Text, {
2087
+ size: 1,
2088
+ children: [taskType && react.createElement(taskType.icon), !task.reason && /* @__PURE__ */jsxRuntime.jsx(ui.Spinner, {})]
2089
+ })
2090
+ }), /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
2091
+ flex: 1,
2092
+ space: 2,
2093
+ children: [/* @__PURE__ */jsxRuntime.jsxs(ui.Text, {
2094
+ size: 1,
2095
+ weight: "medium",
2096
+ children: [taskType ? taskType.title : "Running", task.title && /* @__PURE__ */jsxRuntime.jsxs(jsxRuntime.Fragment, {
2097
+ children: [": ", task.title]
2098
+ })]
2099
+ }), task.message ? /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
2100
+ size: 1,
2101
+ children: task.message
2102
+ }) : null, /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
2103
+ muted: true,
2104
+ size: 1,
2105
+ children: /* @__PURE__ */jsxRuntime.jsx(TimeAgo, {
2106
+ date: (_a2 = task.ended) != null ? _a2 : task.started
2107
+ })
2108
+ })]
2109
+ })]
2110
+ }), !task.ended && /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
2111
+ flex: "none",
2112
+ padding: 1,
2113
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
2114
+ fontSize: 1,
2115
+ mode: "bleed",
2116
+ onClick: task.cancel,
2117
+ text: "Cancel"
2118
+ })
2119
+ })]
2120
+ })
2121
+ });
2122
2122
  }
2123
2123
  var __freeze$4 = Object.freeze;
2124
2124
  var __defProp$4 = Object.defineProperty;
@@ -2521,60 +2521,109 @@ const assistInspector = {
2521
2521
  };
2522
2522
  }
2523
2523
  };
2524
- const AssistDocumentContext = react.createContext(void 0);
2525
- function useAssistDocumentContext() {
2526
- const context = react.useContext(AssistDocumentContext);
2527
- if (!context) {
2528
- throw new Error("AssistDocumentContext value is missing");
2529
- }
2530
- return context;
2524
+ function AssistFeatureBadge() {
2525
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Badge, {
2526
+ fontSize: 0,
2527
+ style: {
2528
+ margin: "-2px 0"
2529
+ },
2530
+ tone: "primary",
2531
+ children: "Beta"
2532
+ });
2531
2533
  }
2532
- const NO_PRESENCE = [];
2533
- function useAssistPresence(path, showFocusWithin) {
2534
- const context = useAssistDocumentContext();
2535
- const assistDocument = context && "assistDocument" in context ? context.assistDocument : void 0;
2536
- const tasks = assistDocument == null ? void 0 : assistDocument.tasks;
2537
- return react.useMemo(() => {
2538
- var _a, _b;
2539
- const activePresence = (_b = (_a = tasks == null ? void 0 : tasks.filter(task => !task.ended)) == null ? void 0 : _a.flatMap(task => {
2540
- var _a2;
2541
- return (_a2 = task.presence) != null ? _a2 : [];
2542
- })) == null ? void 0 : _b.filter(p => p.started && ( /* @__PURE__ */new Date()).getTime() - new Date(p.started).getTime() < maxHistoryVisibilityMs).filter(presence => {
2543
- if (!presence.path || !path.length) {
2544
- return false;
2545
- }
2546
- const statusPath = sanity.stringToPath(presence.path);
2547
- if (!showFocusWithin && statusPath.length !== path.length) {
2548
- return false;
2549
- }
2550
- return path.every((pathSegment, i) => {
2551
- const statusSegment = statusPath[i];
2552
- if (typeof pathSegment === "string") {
2553
- return pathSegment === statusSegment;
2554
- }
2555
- if (sanity.isKeySegment(pathSegment) && sanity.isKeySegment(statusSegment)) {
2556
- return pathSegment._key === statusSegment._key;
2557
- }
2558
- return false;
2559
- });
2560
- });
2561
- if (!(activePresence == null ? void 0 : activePresence.length)) {
2562
- return NO_PRESENCE;
2563
- }
2564
- return activePresence.map(status => aiPresence(status, path));
2565
- }, [showFocusWithin, tasks, path]);
2534
+ function AssistOnboardingPopover(props) {
2535
+ const {
2536
+ dismiss
2537
+ } = props;
2538
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Popover, {
2539
+ content: /* @__PURE__ */jsxRuntime.jsx(AssistIntroCard, {
2540
+ dismiss
2541
+ }),
2542
+ open: true,
2543
+ portal: true,
2544
+ placeholder: "bottom",
2545
+ tone: "default",
2546
+ width: 0,
2547
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
2548
+ radius: 2,
2549
+ shadow: 2,
2550
+ style: {
2551
+ padding: 2,
2552
+ lineHeight: 0
2553
+ },
2554
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
2555
+ disabled: true,
2556
+ fontSize: 1,
2557
+ icon: icons.SparklesIcon,
2558
+ mode: "bleed",
2559
+ padding: 2
2560
+ })
2561
+ })
2562
+ });
2566
2563
  }
2567
- function aiPresence(presence, path, title) {
2568
- var _a;
2569
- return {
2570
- user: {
2571
- id: "sanity-assistant_".concat(presence._key),
2572
- displayName: pluginTitle
2573
- },
2574
- path,
2575
- sessionId: "not-available",
2576
- lastActiveAt: (_a = presence == null ? void 0 : presence.started) != null ? _a : ( /* @__PURE__ */new Date()).toISOString()
2577
- };
2564
+ function AssistIntroCard(props) {
2565
+ const buttonRef = react.useRef(null);
2566
+ return /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
2567
+ as: "section",
2568
+ padding: 3,
2569
+ space: 3,
2570
+ children: [/* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
2571
+ padding: 2,
2572
+ space: 4,
2573
+ children: [/* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
2574
+ gap: 2,
2575
+ align: "center",
2576
+ children: [/* @__PURE__ */jsxRuntime.jsx(ui.Text, {
2577
+ as: "h1",
2578
+ size: 1,
2579
+ weight: "semibold",
2580
+ children: pluginTitle
2581
+ }), /* @__PURE__ */jsxRuntime.jsx("div", {
2582
+ "aria-hidden": true,
2583
+ style: {
2584
+ margin: "-3px 0",
2585
+ lineHeight: 0
2586
+ },
2587
+ children: /* @__PURE__ */jsxRuntime.jsx(AssistFeatureBadge, {})
2588
+ })]
2589
+ }), /* @__PURE__ */jsxRuntime.jsx(ui.Stack, {
2590
+ space: 3,
2591
+ children: /* @__PURE__ */jsxRuntime.jsxs(ui.Text, {
2592
+ as: "p",
2593
+ muted: true,
2594
+ size: 1,
2595
+ children: ["Manage reusable AI instructions to boost your content creation and reduce amount of repetitive chores.", " ", /* @__PURE__ */jsxRuntime.jsxs("a", {
2596
+ href: releaseAnnouncementUrl,
2597
+ target: "_blank",
2598
+ rel: "noreferrer",
2599
+ children: ["Learn more ", /* @__PURE__ */jsxRuntime.jsx(icons.ArrowRightIcon, {})]
2600
+ })]
2601
+ })
2602
+ })]
2603
+ }), /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
2604
+ fontSize: 1,
2605
+ icon: icons.CheckmarkIcon,
2606
+ onClick: props.dismiss,
2607
+ padding: 3,
2608
+ ref: buttonRef,
2609
+ text: "Ok, good to know!",
2610
+ tone: "primary"
2611
+ })]
2612
+ });
2613
+ }
2614
+ const FirstAssistedPathContext = react.createContext(void 0);
2615
+ function FirstAssistedPathProvider(props) {
2616
+ const {
2617
+ members
2618
+ } = props;
2619
+ const firstAssistedPath = react.useMemo(() => {
2620
+ const firstAssisted = members.find(member => member.kind === "field" && isAssistSupported(member.field.schemaType));
2621
+ return (firstAssisted == null ? void 0 : firstAssisted.field.path) ? sanity.pathToString(firstAssisted == null ? void 0 : firstAssisted.field.path) : void 0;
2622
+ }, [members]);
2623
+ return /* @__PURE__ */jsxRuntime.jsx(FirstAssistedPathContext.Provider, {
2624
+ value: firstAssistedPath,
2625
+ children: props.children
2626
+ });
2578
2627
  }
2579
2628
  var __freeze$3 = Object.freeze;
2580
2629
  var __defProp$3 = Object.defineProperty;
@@ -2598,47 +2647,47 @@ const FadeInContent = react.forwardRef(function FadeInContent2(_ref12, ref) {
2598
2647
  });
2599
2648
  });
2600
2649
  const purple = {
2601
- "50": {
2650
+ 50: {
2602
2651
  title: "Purple 50",
2603
2652
  hex: "#f8f5ff"
2604
2653
  },
2605
- "100": {
2654
+ 100: {
2606
2655
  title: "Purple 100",
2607
2656
  hex: "#f1ebff"
2608
2657
  },
2609
- "200": {
2658
+ 200: {
2610
2659
  title: "Purple 200",
2611
2660
  hex: "#ece1fe"
2612
2661
  },
2613
- "300": {
2662
+ 300: {
2614
2663
  title: "Purple 300",
2615
2664
  hex: "#ccb1fc"
2616
2665
  },
2617
- "400": {
2666
+ 400: {
2618
2667
  title: "Purple 400",
2619
2668
  hex: "#b087f7"
2620
2669
  },
2621
- "500": {
2670
+ 500: {
2622
2671
  title: "Purple 500",
2623
2672
  hex: "#8f57ef"
2624
2673
  },
2625
- "600": {
2674
+ 600: {
2626
2675
  title: "Purple 600",
2627
2676
  hex: "#721fe5"
2628
2677
  },
2629
- "700": {
2678
+ 700: {
2630
2679
  title: "Purple 700",
2631
2680
  hex: "#4c1a9e"
2632
2681
  },
2633
- "800": {
2682
+ 800: {
2634
2683
  title: "Purple 800",
2635
2684
  hex: "#2f1862"
2636
2685
  },
2637
- "900": {
2686
+ 900: {
2638
2687
  title: "Purple 900",
2639
2688
  hex: "#23173f"
2640
2689
  },
2641
- "950": {
2690
+ 950: {
2642
2691
  title: "Purple 950",
2643
2692
  hex: "#181128"
2644
2693
  }
@@ -2685,154 +2734,105 @@ function AssistAvatar(props) {
2685
2734
  r: "11.75"
2686
2735
  })
2687
2736
  }), /* @__PURE__ */jsxRuntime.jsx(IconDisc, {
2688
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
2689
- as: "span",
2690
- size: 0,
2691
- style: {
2692
- color: "inherit"
2693
- },
2694
- children: /* @__PURE__ */jsxRuntime.jsx(icons.SparklesIcon, {
2695
- style: {
2696
- color: "inherit"
2697
- }
2698
- })
2699
- })
2700
- })]
2701
- });
2702
- }
2703
- function AiFieldPresence(props) {
2704
- return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
2705
- style: {
2706
- position: "relative",
2707
- background: "transparent"
2708
- },
2709
- contentEditable: false,
2710
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Tooltip, {
2711
- placement: "left",
2712
- content: /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
2713
- padding: 3,
2714
- border: true,
2715
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
2716
- align: "center",
2717
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
2718
- size: 1,
2719
- children: "Running instruction..."
2720
- })
2721
- })
2722
- }),
2723
- children: /* @__PURE__ */jsxRuntime.jsx(FadeInContent, {
2724
- durationMs: 300,
2725
- children: /* @__PURE__ */jsxRuntime.jsx(AssistAvatar, {
2726
- state: "active"
2727
- })
2728
- })
2729
- })
2730
- });
2731
- }
2732
- function AssistFeatureBadge() {
2733
- return /* @__PURE__ */jsxRuntime.jsx(ui.Badge, {
2734
- fontSize: 0,
2735
- style: {
2736
- margin: "-2px 0"
2737
- },
2738
- tone: "primary",
2739
- children: "Beta"
2740
- });
2741
- }
2742
- function AssistOnboardingPopover(props) {
2743
- const {
2744
- dismiss
2745
- } = props;
2746
- return /* @__PURE__ */jsxRuntime.jsx(ui.Popover, {
2747
- content: /* @__PURE__ */jsxRuntime.jsx(AssistIntroCard, {
2748
- dismiss
2749
- }),
2750
- open: true,
2751
- portal: true,
2752
- placeholder: "bottom",
2753
- tone: "default",
2754
- width: 0,
2755
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
2756
- radius: 2,
2757
- shadow: 2,
2758
- style: {
2759
- padding: 2,
2760
- lineHeight: 0
2761
- },
2762
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
2763
- disabled: true,
2764
- fontSize: 1,
2765
- icon: icons.SparklesIcon,
2766
- mode: "bleed",
2767
- padding: 2
2768
- })
2769
- })
2770
- });
2771
- }
2772
- function AssistIntroCard(props) {
2773
- const buttonRef = react.useRef(null);
2774
- return /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
2775
- as: "section",
2776
- padding: 3,
2777
- space: 3,
2778
- children: [/* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
2779
- padding: 2,
2780
- space: 4,
2781
- children: [/* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
2782
- gap: 2,
2783
- align: "center",
2784
- children: [/* @__PURE__ */jsxRuntime.jsx(ui.Text, {
2785
- as: "h1",
2786
- size: 1,
2787
- weight: "semibold",
2788
- children: pluginTitle
2789
- }), /* @__PURE__ */jsxRuntime.jsx("div", {
2790
- "aria-hidden": true,
2737
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
2738
+ as: "span",
2739
+ size: 0,
2740
+ style: {
2741
+ color: "inherit"
2742
+ },
2743
+ children: /* @__PURE__ */jsxRuntime.jsx(icons.SparklesIcon, {
2791
2744
  style: {
2792
- margin: "-3px 0",
2793
- lineHeight: 0
2794
- },
2795
- children: /* @__PURE__ */jsxRuntime.jsx(AssistFeatureBadge, {})
2796
- })]
2797
- }), /* @__PURE__ */jsxRuntime.jsx(ui.Stack, {
2798
- space: 3,
2799
- children: /* @__PURE__ */jsxRuntime.jsxs(ui.Text, {
2800
- as: "p",
2801
- muted: true,
2802
- size: 1,
2803
- children: ["Manage reusable AI instructions to boost your content creation and reduce amount of repetitive chores.", " ", /* @__PURE__ */jsxRuntime.jsxs("a", {
2804
- href: releaseAnnouncementUrl,
2805
- target: "_blank",
2806
- rel: "noreferrer",
2807
- children: ["Learn more ", /* @__PURE__ */jsxRuntime.jsx(icons.ArrowRightIcon, {})]
2808
- })]
2745
+ color: "inherit"
2746
+ }
2809
2747
  })
2810
- })]
2811
- }), /* @__PURE__ */jsxRuntime.jsx(ui.Button, {
2812
- fontSize: 1,
2813
- icon: icons.CheckmarkIcon,
2814
- onClick: props.dismiss,
2815
- padding: 3,
2816
- ref: buttonRef,
2817
- text: "Ok, good to know!",
2818
- tone: "primary"
2748
+ })
2819
2749
  })]
2820
2750
  });
2821
2751
  }
2822
- const FirstAssistedPathContext = react.createContext(void 0);
2823
- function FirstAssistedPathProvider(props) {
2824
- const {
2825
- members
2826
- } = props;
2827
- const firstAssistedPath = react.useMemo(() => {
2828
- const firstAssisted = members.find(member => member.kind === "field" && isAssistSupported(member.field.schemaType));
2829
- return (firstAssisted == null ? void 0 : firstAssisted.field.path) ? sanity.pathToString(firstAssisted == null ? void 0 : firstAssisted.field.path) : void 0;
2830
- }, [members]);
2831
- return /* @__PURE__ */jsxRuntime.jsx(FirstAssistedPathContext.Provider, {
2832
- value: firstAssistedPath,
2833
- children: props.children
2752
+ function AiFieldPresence(props) {
2753
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
2754
+ style: {
2755
+ position: "relative",
2756
+ background: "transparent"
2757
+ },
2758
+ contentEditable: false,
2759
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Tooltip, {
2760
+ placement: "left",
2761
+ content: /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
2762
+ padding: 3,
2763
+ border: true,
2764
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
2765
+ align: "center",
2766
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
2767
+ size: 1,
2768
+ children: "Running instruction..."
2769
+ })
2770
+ })
2771
+ }),
2772
+ children: /* @__PURE__ */jsxRuntime.jsx(FadeInContent, {
2773
+ durationMs: 300,
2774
+ children: /* @__PURE__ */jsxRuntime.jsx(AssistAvatar, {
2775
+ state: "active"
2776
+ })
2777
+ })
2778
+ })
2834
2779
  });
2835
2780
  }
2781
+ const AssistDocumentContext = react.createContext(void 0);
2782
+ function useAssistDocumentContext() {
2783
+ const context = react.useContext(AssistDocumentContext);
2784
+ if (!context) {
2785
+ throw new Error("AssistDocumentContext value is missing");
2786
+ }
2787
+ return context;
2788
+ }
2789
+ const NO_PRESENCE = [];
2790
+ function useAssistPresence(path, showFocusWithin) {
2791
+ const context = useAssistDocumentContext();
2792
+ const assistDocument = context && "assistDocument" in context ? context.assistDocument : void 0;
2793
+ const tasks = assistDocument == null ? void 0 : assistDocument.tasks;
2794
+ return react.useMemo(() => {
2795
+ var _a, _b;
2796
+ const activePresence = (_b = (_a = tasks == null ? void 0 : tasks.filter(task => !task.ended)) == null ? void 0 : _a.flatMap(task => {
2797
+ var _a2;
2798
+ return (_a2 = task.presence) != null ? _a2 : [];
2799
+ })) == null ? void 0 : _b.filter(p => p.started && ( /* @__PURE__ */new Date()).getTime() - new Date(p.started).getTime() < maxHistoryVisibilityMs).filter(presence => {
2800
+ if (!presence.path || !path.length) {
2801
+ return false;
2802
+ }
2803
+ const statusPath = sanity.stringToPath(presence.path);
2804
+ if (!showFocusWithin && statusPath.length !== path.length) {
2805
+ return false;
2806
+ }
2807
+ return path.every((pathSegment, i) => {
2808
+ const statusSegment = statusPath[i];
2809
+ if (typeof pathSegment === "string") {
2810
+ return pathSegment === statusSegment;
2811
+ }
2812
+ if (sanity.isKeySegment(pathSegment) && sanity.isKeySegment(statusSegment)) {
2813
+ return pathSegment._key === statusSegment._key;
2814
+ }
2815
+ return false;
2816
+ });
2817
+ });
2818
+ if (!(activePresence == null ? void 0 : activePresence.length)) {
2819
+ return NO_PRESENCE;
2820
+ }
2821
+ return activePresence.map(status => aiPresence(status, path));
2822
+ }, [showFocusWithin, tasks, path]);
2823
+ }
2824
+ function aiPresence(presence, path, title) {
2825
+ var _a;
2826
+ return {
2827
+ user: {
2828
+ id: "sanity-assistant_".concat(presence._key),
2829
+ displayName: pluginTitle
2830
+ },
2831
+ path,
2832
+ sessionId: "not-available",
2833
+ lastActiveAt: (_a = presence == null ? void 0 : presence.started) != null ? _a : ( /* @__PURE__ */new Date()).toISOString()
2834
+ };
2835
+ }
2836
2836
  function AssistFieldWrapper(props) {
2837
2837
  const {
2838
2838
  schemaType
@@ -2883,14 +2883,6 @@ function AssistField(props) {
2883
2883
  __internal_slot: actions
2884
2884
  });
2885
2885
  }
2886
- const ConnectorsStoreContext = react.createContext(null);
2887
- function useConnectorsStore() {
2888
- const store = react.useContext(ConnectorsStoreContext);
2889
- if (!store) {
2890
- throw new Error("Missing connectors store context");
2891
- }
2892
- return store;
2893
- }
2894
2886
  function hasOverflowScroll(el) {
2895
2887
  const overflow = getComputedStyle(el).overflow;
2896
2888
  return overflow.includes("auto") || overflow.includes("hidden") || overflow.includes("scroll");
@@ -3028,6 +3020,14 @@ function ConnectorRegion(props) {
3028
3020
  children
3029
3021
  });
3030
3022
  }
3023
+ const ConnectorsStoreContext = react.createContext(null);
3024
+ function useConnectorsStore() {
3025
+ const store = react.useContext(ConnectorsStoreContext);
3026
+ if (!store) {
3027
+ throw new Error("Missing connectors store context");
3028
+ }
3029
+ return store;
3030
+ }
3031
3031
  function ConnectFromRegion(props) {
3032
3032
  const {
3033
3033
  children,
@@ -4982,117 +4982,44 @@ function AssistItem(props) {
4982
4982
  }, pre.user.id))]
4983
4983
  });
4984
4984
  }
4985
- function findFieldMember(members, fieldName) {
4986
- return members.find(m => m.kind === "field" && m.name === fieldName || m.kind === "error" && m.fieldName === fieldName);
4987
- }
4988
- function findFieldsetMember(members, fieldsetName) {
4989
- return members.find(m => m.kind === "fieldSet" && m.fieldSet.name === fieldsetName);
4990
- }
4991
- function InstructionInput(props) {
4992
- return /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
4993
- space: [4, 4, 4, 5],
4994
- children: [/* @__PURE__ */jsxRuntime.jsx(NameField, {
4995
- ...props
4996
- }), /* @__PURE__ */jsxRuntime.jsx(ShareField, {
4997
- ...props
4998
- }), /* @__PURE__ */jsxRuntime.jsx(ObjectMember, {
4999
- fieldName: "prompt",
5000
- ...props
5001
- }), /* @__PURE__ */jsxRuntime.jsx(ObjectMember, {
5002
- fieldName: "output",
5003
- ...props
5004
- })]
5005
- });
5006
- }
5007
- function ObjectMember(_ref13) {
5008
- let {
5009
- fieldName,
5010
- ...props
5011
- } = _ref13;
5012
- const member = findFieldMember(props.members, fieldName);
5013
- return member ? /* @__PURE__ */jsxRuntime.jsx(sanity.ObjectInputMember, {
5014
- ...props,
5015
- member
5016
- }) : null;
5017
- }
5018
- const NONE = [];
5019
- function NameField(props) {
5020
- var _a;
5021
- const fieldsetMember = findFieldsetMember(props.members, "appearance");
5022
- const titleId = react.useId();
5023
- const members = (_a = fieldsetMember == null ? void 0 : fieldsetMember.fieldSet.members) != null ? _a : NONE;
5024
- const iconMember = findFieldMember(members, "icon");
5025
- const titleMember = findFieldMember(members, "title");
5026
- const titlePlaceholder = "Untitled";
5027
- const moddedTitleMember = react.useMemo(() => {
5028
- if (!titleMember) {
5029
- return void 0;
5030
- }
5031
- if (titleMember.kind === "error") {
5032
- return titleMember;
5033
- }
5034
- return {
5035
- ...titleMember,
5036
- field: {
5037
- ...(titleMember == null ? void 0 : titleMember.field),
5038
- schemaType: {
5039
- ...(titleMember == null ? void 0 : titleMember.field.schemaType),
5040
- placeholder: titlePlaceholder
5041
- }
5042
- }
5043
- };
5044
- }, [titleMember, titlePlaceholder]);
5045
- return /* @__PURE__ */jsxRuntime.jsx(ui.Stack, {
5046
- space: 5,
5047
- children: /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
5048
- space: 2,
5049
- children: [/* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
5050
- gap: 1,
5051
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
5052
- as: "label",
5053
- weight: "semibold",
5054
- size: 1,
5055
- htmlFor: titleId,
5056
- children: "Name"
5057
- })
5058
- }), /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
5059
- muted: true,
5060
- size: 1,
5061
- children: "How this instruction appears in menus"
5062
- }), /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
5063
- align: "center",
5064
- children: [iconMember && /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
5065
- flex: "none",
5066
- children: /* @__PURE__ */jsxRuntime.jsx(sanity.ObjectInputMember, {
5067
- ...props,
5068
- member: iconMember
5069
- })
5070
- }), moddedTitleMember && /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
5071
- flex: 1,
5072
- style: {
5073
- marginLeft: -1
5074
- },
5075
- children: /* @__PURE__ */jsxRuntime.jsx(sanity.ObjectInputMember, {
5076
- ...props,
5077
- member: moddedTitleMember
5078
- })
5079
- })]
5080
- })]
5081
- })
5082
- });
5083
- }
5084
- function ShareField(props) {
5085
- var _a;
5086
- const fieldsetMember = findFieldsetMember(props.members, "appearance");
5087
- const members = (_a = fieldsetMember == null ? void 0 : fieldsetMember.fieldSet.members) != null ? _a : NONE;
5088
- const visibilityMember = findFieldMember(members, "userId");
5089
- return /* @__PURE__ */jsxRuntime.jsx(jsxRuntime.Fragment, {
5090
- children: visibilityMember && /* @__PURE__ */jsxRuntime.jsx(sanity.ObjectInputMember, {
5091
- ...props,
5092
- member: visibilityMember
4985
+ const InlineBlockValueContext = react.createContext(void 0);
4986
+ function AssistInlineFormBlock(props) {
4987
+ return /* @__PURE__ */jsxRuntime.jsx(InlineBlockValueContext.Provider, {
4988
+ value: props.value,
4989
+ children: /* @__PURE__ */jsxRuntime.jsx(jsxRuntime.Fragment, {
4990
+ children: props.renderDefault(props)
5093
4991
  })
5094
4992
  });
5095
4993
  }
4994
+ function FieldRefPreview(props) {
4995
+ var _a, _b, _c, _d;
4996
+ const documentSchema = (_a = react.useContext(SelectedFieldContext)) == null ? void 0 : _a.documentSchema;
4997
+ const path = (_c = (_b = react.useContext(InlineBlockValueContext)) == null ? void 0 : _b.path) != null ? _c : props.path;
4998
+ const selectedField = useSelectedField(documentSchema, path);
4999
+ return /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
5000
+ gap: 2,
5001
+ align: "center",
5002
+ style: {
5003
+ width: "100%"
5004
+ },
5005
+ children: [/* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
5006
+ flex: 1,
5007
+ gap: 2,
5008
+ align: "center",
5009
+ paddingY: 3,
5010
+ paddingX: 1,
5011
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
5012
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
5013
+ size: 1,
5014
+ textOverflow: "ellipsis",
5015
+ children: (_d = selectedField == null ? void 0 : selectedField.title) != null ? _d : "Select field"
5016
+ })
5017
+ })
5018
+ }), /* @__PURE__ */jsxRuntime.jsx(jsxRuntime.Fragment, {
5019
+ children: props.actions
5020
+ })]
5021
+ });
5022
+ }
5096
5023
  function HiddenFieldTitle(props) {
5097
5024
  return props.renderDefault({
5098
5025
  ...props,
@@ -5101,54 +5028,14 @@ function HiddenFieldTitle(props) {
5101
5028
  changed: false
5102
5029
  });
5103
5030
  }
5104
- function InstructionVisibility(props) {
5105
- const {
5106
- value,
5107
- onChange
5108
- } = props;
5109
- const user = sanity.useCurrentUser();
5110
- const handleChange = react.useCallback(() => {
5111
- var _a;
5112
- const newValue = value ? "" : (_a = user == null ? void 0 : user.id) != null ? _a : "";
5113
- onChange(newValue ? sanity.set(newValue) : sanity.unset());
5114
- }, [onChange, user, value]);
5115
- const id = react.useId();
5116
- return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
5117
- children: /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
5118
- gap: 2,
5119
- align: "flex-start",
5120
- children: [/* @__PURE__ */jsxRuntime.jsx("div", {
5121
- style: {
5122
- margin: "-3px 0"
5123
- },
5124
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Switch, {
5125
- ...props.elementProps,
5126
- id,
5127
- value: "".concat(!value),
5128
- checked: !value,
5129
- onChange: handleChange,
5130
- disabled: props.elementProps.readOnly
5131
- })
5132
- }), /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
5133
- muted: true,
5134
- size: 1,
5135
- weight: "medium",
5136
- children: /* @__PURE__ */jsxRuntime.jsx("label", {
5137
- htmlFor: id,
5138
- children: "Make visible to all Studio members"
5139
- })
5140
- })]
5141
- })
5142
- });
5143
- }
5144
5031
  function IconInput(props) {
5145
5032
  const {
5146
5033
  value,
5147
5034
  onChange
5148
5035
  } = props;
5149
5036
  const id = react.useId();
5150
- const items = react.useMemo(() => Object.entries(icons.icons).map(_ref14 => {
5151
- let [key, icon] = _ref14;
5037
+ const items = react.useMemo(() => Object.entries(icons.icons).map(_ref13 => {
5038
+ let [key, icon] = _ref13;
5152
5039
  return /* @__PURE__ */jsxRuntime.jsx(IconItem, {
5153
5040
  iconKey: key,
5154
5041
  icon,
@@ -5176,12 +5063,12 @@ function IconInput(props) {
5176
5063
  }
5177
5064
  });
5178
5065
  }
5179
- function IconItem(_ref15) {
5066
+ function IconItem(_ref14) {
5180
5067
  let {
5181
5068
  icon,
5182
5069
  iconKey: key,
5183
5070
  onChange
5184
- } = _ref15;
5071
+ } = _ref14;
5185
5072
  const onClick = react.useCallback(() => onChange(sanity.set(key)), [onChange, key]);
5186
5073
  return /* @__PURE__ */jsxRuntime.jsx(ui.MenuItem, {
5187
5074
  icon,
@@ -5192,11 +5079,51 @@ function IconItem(_ref15) {
5192
5079
  }
5193
5080
  function getIcon(iconName) {
5194
5081
  var _a, _b;
5195
- return (_b = (_a = Object.entries(icons.icons).find(_ref16 => {
5196
- let [key] = _ref16;
5082
+ return (_b = (_a = Object.entries(icons.icons).find(_ref15 => {
5083
+ let [key] = _ref15;
5197
5084
  return key === iconName;
5198
5085
  })) == null ? void 0 : _a[1]) != null ? _b : icons.icons.sparkles;
5199
5086
  }
5087
+ function InstructionVisibility(props) {
5088
+ const {
5089
+ value,
5090
+ onChange
5091
+ } = props;
5092
+ const user = sanity.useCurrentUser();
5093
+ const handleChange = react.useCallback(() => {
5094
+ var _a;
5095
+ const newValue = value ? "" : (_a = user == null ? void 0 : user.id) != null ? _a : "";
5096
+ onChange(newValue ? sanity.set(newValue) : sanity.unset());
5097
+ }, [onChange, user, value]);
5098
+ const id = react.useId();
5099
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
5100
+ children: /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
5101
+ gap: 2,
5102
+ align: "flex-start",
5103
+ children: [/* @__PURE__ */jsxRuntime.jsx("div", {
5104
+ style: {
5105
+ margin: "-3px 0"
5106
+ },
5107
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Switch, {
5108
+ ...props.elementProps,
5109
+ id,
5110
+ value: "".concat(!value),
5111
+ checked: !value,
5112
+ onChange: handleChange,
5113
+ disabled: props.elementProps.readOnly
5114
+ })
5115
+ }), /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
5116
+ muted: true,
5117
+ size: 1,
5118
+ weight: "medium",
5119
+ children: /* @__PURE__ */jsxRuntime.jsx("label", {
5120
+ htmlFor: id,
5121
+ children: "Make visible to all Studio members"
5122
+ })
5123
+ })]
5124
+ })
5125
+ });
5126
+ }
5200
5127
  function FieldRefPathInput(props) {
5201
5128
  var _a;
5202
5129
  const documentSchema = (_a = react.useContext(SelectedFieldContext)) == null ? void 0 : _a.documentSchema;
@@ -5241,209 +5168,115 @@ function FieldRefPathInput(props) {
5241
5168
  })
5242
5169
  });
5243
5170
  }
5244
- function InstructionsArrayInput(props) {
5245
- const user = sanity.useCurrentUser();
5246
- const originalValue = props.value;
5247
- const originalMembers = props.members;
5248
- const value = react.useMemo(() => (originalValue != null ? originalValue : []).filter(v => !v.userId || v.userId === (user == null ? void 0 : user.id)), [originalValue, user]);
5249
- const members = react.useMemo(() => (originalMembers != null ? originalMembers : []).filter(v => {
5250
- var _a;
5251
- if (v.kind === "error") {
5252
- return true;
5253
- }
5254
- const value2 = (_a = v == null ? void 0 : v.item) == null ? void 0 : _a.value;
5255
- return !value2.userId || value2.userId === (user == null ? void 0 : user.id);
5256
- }), [originalMembers, user]);
5257
- return props.renderDefault({
5258
- ...props,
5259
- value,
5260
- members
5261
- });
5262
- }
5263
- const InlineBlockValueContext = react.createContext(void 0);
5264
- function AssistInlineFormBlock(props) {
5265
- return /* @__PURE__ */jsxRuntime.jsx(InlineBlockValueContext.Provider, {
5266
- value: props.value,
5267
- children: /* @__PURE__ */jsxRuntime.jsx(jsxRuntime.Fragment, {
5268
- children: props.renderDefault(props)
5269
- })
5270
- });
5271
- }
5272
- function FieldRefPreview(props) {
5273
- var _a, _b, _c, _d;
5274
- const documentSchema = (_a = react.useContext(SelectedFieldContext)) == null ? void 0 : _a.documentSchema;
5275
- const path = (_c = (_b = react.useContext(InlineBlockValueContext)) == null ? void 0 : _b.path) != null ? _c : props.path;
5276
- const selectedField = useSelectedField(documentSchema, path);
5277
- return /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
5278
- gap: 2,
5279
- align: "center",
5280
- style: {
5281
- width: "100%"
5282
- },
5283
- children: [/* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
5284
- flex: 1,
5285
- gap: 2,
5286
- align: "center",
5287
- paddingY: 3,
5288
- paddingX: 1,
5289
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
5290
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
5291
- size: 1,
5292
- textOverflow: "ellipsis",
5293
- children: (_d = selectedField == null ? void 0 : selectedField.title) != null ? _d : "Select field"
5294
- })
5295
- })
5296
- }), /* @__PURE__ */jsxRuntime.jsx(jsxRuntime.Fragment, {
5297
- children: props.actions
5298
- })]
5299
- });
5300
- }
5301
- function HideReferenceChangedBannerInput(props) {
5302
- const ref = react.useRef(null);
5303
- react.useEffect(() => {
5304
- var _a;
5305
- const parent = (_a = ref.current) == null ? void 0 : _a.closest('[data-testid="pane-content"]');
5306
- if (!parent) {
5307
- return;
5308
- }
5309
- const style = document.createElement("style");
5310
- const parentId = "id-".concat(Math.random()).replace(".", "-");
5311
- parent.id = parentId;
5312
- style.innerText = "\n #".concat(parentId, ' [data-testid="reference-changed-banner"] { display: none; }\n ');
5313
- parent.prepend(style);
5314
- }, [ref]);
5315
- return /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
5316
- ref,
5317
- children: props.renderDefault(props)
5318
- });
5319
- }
5320
- const contextDocumentSchema = sanity.defineType({
5321
- type: "document",
5322
- name: contextDocumentTypeName,
5323
- title: "AI context",
5324
- liveEdit: true,
5325
- icon: icons.TokenIcon,
5326
- components: {
5327
- input: HideReferenceChangedBannerInput
5328
- },
5329
- fields: [sanity.defineField({
5330
- type: "string",
5331
- name: "title",
5332
- title: "Title"
5333
- }), sanity.defineField({
5334
- name: "context",
5335
- type: "array",
5336
- title: "Context",
5337
- of: [sanity.defineArrayMember({
5338
- type: "block",
5339
- styles: [{
5340
- title: "Normal",
5341
- value: "normal"
5342
- }],
5343
- lists: [],
5344
- marks: {
5345
- decorators: [],
5346
- annotations: []
5347
- }
5348
- })]
5349
- })],
5350
- preview: {
5351
- select: {
5352
- title: "title",
5353
- context: "context"
5354
- },
5355
- prepare(_ref17) {
5356
- let {
5357
- title,
5358
- context
5359
- } = _ref17;
5360
- var _a;
5361
- const text = context == null ? void 0 : context.flatMap(block => block == null ? void 0 : block.children).flatMap(child => {
5362
- var _a2;
5363
- return (_a2 = child == null ? void 0 : child.text) == null ? void 0 : _a2.split(" ");
5364
- }).filter(Boolean);
5365
- const words = (_a = text == null ? void 0 : text.length) != null ? _a : 0;
5366
- return {
5367
- title,
5368
- subtitle: "Words: ".concat(words),
5369
- media: icons.DocumentTextIcon
5370
- };
5371
- }
5372
- }
5373
- });
5374
-
5375
- // Strict ESM env, designed to run outside Node.js in envs that provide WebCrypto (deno, browsers, etc)
5376
-
5377
- function getRandomValues(typedArray) {
5378
- const crypto = typeof window !== 'undefined' && 'crypto' in window ? window.crypto : globalThis.crypto;
5379
- if (!crypto || !crypto.getRandomValues) {
5380
- throw new Error('WebCrypto not available in this environment');
5381
- }
5382
- return crypto.getRandomValues(typedArray);
5383
- }
5384
- function whatwgRNG() {
5385
- let length = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 16;
5386
- const rnds8 = new Uint8Array(length);
5387
- getRandomValues(rnds8);
5388
- return rnds8;
5171
+ function findFieldMember(members, fieldName) {
5172
+ return members.find(m => m.kind === "field" && m.name === fieldName || m.kind === "error" && m.fieldName === fieldName);
5389
5173
  }
5390
- const getByteHexTable = /* @__PURE__ */(() => {
5391
- let table;
5392
- return () => {
5393
- if (table) {
5394
- return table;
5395
- }
5396
- table = [];
5397
- for (let i = 0; i < 256; ++i) {
5398
- table[i] = (i + 256).toString(16).substring(1);
5399
- }
5400
- return table;
5401
- };
5402
- })();
5403
- function randomKey(length) {
5404
- const table = getByteHexTable();
5405
- return whatwgRNG(length).reduce((str, n) => str + table[n], "").slice(0, length);
5174
+ function findFieldsetMember(members, fieldsetName) {
5175
+ return members.find(m => m.kind === "fieldSet" && m.fieldSet.name === fieldsetName);
5406
5176
  }
5407
- var __freeze = Object.freeze;
5408
- var __defProp = Object.defineProperty;
5409
- var __template = (cooked, raw) => __freeze(__defProp(cooked, "raw", {
5410
- value: __freeze(raw || cooked.slice())
5411
- }));
5412
- var _a;
5413
- const PteMods = styled__default.default(ui.Box)(_a || (_a = __template(["\n & [data-testid='pt-editor__toolbar-card'] > div > div:last-child {\n display: none;\n }\n & [data-testid='pt-editor'] {\n min-height: 300px;\n }\n & [data-testid='pt-editor'] .pt-inline-object * {\n max-width: 400px;\n }\n"])));
5414
- function PromptInput(props) {
5415
- useOnlyInlineBlocks(props);
5416
- return /* @__PURE__ */jsxRuntime.jsx(PteMods, {
5417
- children: props.renderDefault(props)
5177
+ function InstructionInput(props) {
5178
+ return /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
5179
+ space: [4, 4, 4, 5],
5180
+ children: [/* @__PURE__ */jsxRuntime.jsx(NameField, {
5181
+ ...props
5182
+ }), /* @__PURE__ */jsxRuntime.jsx(ShareField, {
5183
+ ...props
5184
+ }), /* @__PURE__ */jsxRuntime.jsx(ObjectMember, {
5185
+ fieldName: "prompt",
5186
+ ...props
5187
+ }), /* @__PURE__ */jsxRuntime.jsx(ObjectMember, {
5188
+ fieldName: "output",
5189
+ ...props
5190
+ })]
5418
5191
  });
5419
5192
  }
5420
- function useOnlyInlineBlocks(props) {
5421
- react.useEffect(() => {
5422
- var _a2;
5423
- let needsFix = false;
5424
- const val = ((_a2 = props.value) != null ? _a2 : []).map(block => {
5425
- if (block._type === "block") {
5426
- return block;
5427
- }
5428
- needsFix = true;
5429
- return sanity.typed({
5430
- _key: randomKey(12),
5431
- _type: "block",
5432
- level: 0,
5433
- markDefs: [],
5434
- style: "normal",
5435
- children: [block]
5436
- });
5437
- });
5438
- if (needsFix) {
5439
- props.onChange(sanity.set(val));
5193
+ function ObjectMember(_ref16) {
5194
+ let {
5195
+ fieldName,
5196
+ ...props
5197
+ } = _ref16;
5198
+ const member = findFieldMember(props.members, fieldName);
5199
+ return member ? /* @__PURE__ */jsxRuntime.jsx(sanity.ObjectInputMember, {
5200
+ ...props,
5201
+ member
5202
+ }) : null;
5203
+ }
5204
+ const NONE = [];
5205
+ function NameField(props) {
5206
+ var _a;
5207
+ const fieldsetMember = findFieldsetMember(props.members, "appearance");
5208
+ const titleId = react.useId();
5209
+ const members = (_a = fieldsetMember == null ? void 0 : fieldsetMember.fieldSet.members) != null ? _a : NONE;
5210
+ const iconMember = findFieldMember(members, "icon");
5211
+ const titleMember = findFieldMember(members, "title");
5212
+ const titlePlaceholder = "Untitled";
5213
+ const moddedTitleMember = react.useMemo(() => {
5214
+ if (!titleMember) {
5215
+ return void 0;
5440
5216
  }
5441
- }, []);
5217
+ if (titleMember.kind === "error") {
5218
+ return titleMember;
5219
+ }
5220
+ return {
5221
+ ...titleMember,
5222
+ field: {
5223
+ ...(titleMember == null ? void 0 : titleMember.field),
5224
+ schemaType: {
5225
+ ...(titleMember == null ? void 0 : titleMember.field.schemaType),
5226
+ placeholder: titlePlaceholder
5227
+ }
5228
+ }
5229
+ };
5230
+ }, [titleMember, titlePlaceholder]);
5231
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Stack, {
5232
+ space: 5,
5233
+ children: /* @__PURE__ */jsxRuntime.jsxs(ui.Stack, {
5234
+ space: 2,
5235
+ children: [/* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
5236
+ gap: 1,
5237
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
5238
+ as: "label",
5239
+ weight: "semibold",
5240
+ size: 1,
5241
+ htmlFor: titleId,
5242
+ children: "Name"
5243
+ })
5244
+ }), /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
5245
+ muted: true,
5246
+ size: 1,
5247
+ children: "How this instruction appears in menus"
5248
+ }), /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
5249
+ align: "center",
5250
+ children: [iconMember && /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
5251
+ flex: "none",
5252
+ children: /* @__PURE__ */jsxRuntime.jsx(sanity.ObjectInputMember, {
5253
+ ...props,
5254
+ member: iconMember
5255
+ })
5256
+ }), moddedTitleMember && /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
5257
+ flex: 1,
5258
+ style: {
5259
+ marginLeft: -1
5260
+ },
5261
+ children: /* @__PURE__ */jsxRuntime.jsx(sanity.ObjectInputMember, {
5262
+ ...props,
5263
+ member: moddedTitleMember
5264
+ })
5265
+ })]
5266
+ })]
5267
+ })
5268
+ });
5442
5269
  }
5443
- function InstructionsArrayField(props) {
5444
- return props.renderDefault({
5445
- ...props,
5446
- title: " "
5270
+ function ShareField(props) {
5271
+ var _a;
5272
+ const fieldsetMember = findFieldsetMember(props.members, "appearance");
5273
+ const members = (_a = fieldsetMember == null ? void 0 : fieldsetMember.fieldSet.members) != null ? _a : NONE;
5274
+ const visibilityMember = findFieldMember(members, "userId");
5275
+ return /* @__PURE__ */jsxRuntime.jsx(jsxRuntime.Fragment, {
5276
+ children: visibilityMember && /* @__PURE__ */jsxRuntime.jsx(sanity.ObjectInputMember, {
5277
+ ...props,
5278
+ member: visibilityMember
5279
+ })
5447
5280
  });
5448
5281
  }
5449
5282
  function InstructionOutputField(props) {
@@ -5460,11 +5293,11 @@ function InstructionOutputField(props) {
5460
5293
  children: props.children
5461
5294
  });
5462
5295
  }
5463
- function EnabledOutputField(_ref18) {
5296
+ function EnabledOutputField(_ref17) {
5464
5297
  let {
5465
5298
  fieldSchema,
5466
5299
  ...props
5467
- } = _ref18;
5300
+ } = _ref17;
5468
5301
  var _a;
5469
5302
  const [open, setOpen] = react.useState(!!((_a = props.value) == null ? void 0 : _a.length));
5470
5303
  const onExpand = react.useCallback(() => setOpen(true), []);
@@ -5512,11 +5345,11 @@ function useEmptySelectAllValue(value, allowedValues, onChange) {
5512
5345
  }
5513
5346
  }, [allowedValues, value, onChange]);
5514
5347
  }
5515
- function ObjectOutputInput(_ref19) {
5348
+ function ObjectOutputInput(_ref18) {
5516
5349
  let {
5517
5350
  fieldSchema,
5518
5351
  ...props
5519
- } = _ref19;
5352
+ } = _ref18;
5520
5353
  const {
5521
5354
  value,
5522
5355
  onChange
@@ -5563,11 +5396,11 @@ function ObjectOutputInput(_ref19) {
5563
5396
  })
5564
5397
  });
5565
5398
  }
5566
- function ArrayOutputInput(_ref20) {
5399
+ function ArrayOutputInput(_ref19) {
5567
5400
  let {
5568
5401
  fieldSchema,
5569
5402
  ...props
5570
- } = _ref20;
5403
+ } = _ref19;
5571
5404
  const {
5572
5405
  value,
5573
5406
  onChange
@@ -5588,58 +5421,225 @@ function ArrayOutputInput(_ref20) {
5588
5421
  }));
5589
5422
  onChange(sanity.PatchEvent.from([sanity.setIfMissing([]), sanity.insert(items, "after", [-1])]));
5590
5423
  }
5591
- } else {
5592
- const patchValue = {
5593
- _key: selectedValue,
5594
- _type: "sanity.assist.output.type",
5595
- type: selectedValue
5596
- };
5597
- onChange(sanity.PatchEvent.from([sanity.setIfMissing([]), sanity.insert([patchValue], "after", [-1])]));
5424
+ } else {
5425
+ const patchValue = {
5426
+ _key: selectedValue,
5427
+ _type: "sanity.assist.output.type",
5428
+ type: selectedValue
5429
+ };
5430
+ onChange(sanity.PatchEvent.from([sanity.setIfMissing([]), sanity.insert([patchValue], "after", [-1])]));
5431
+ }
5432
+ }, [onChange, value, ofItems]);
5433
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Stack, {
5434
+ space: 2,
5435
+ children: ofItems.map(itemType => {
5436
+ var _a;
5437
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
5438
+ children: /* @__PURE__ */jsxRuntime.jsx(Selectable, {
5439
+ value: itemType.name,
5440
+ title: isType(itemType, "block") ? "Text" : (_a = itemType.title) != null ? _a : itemType.name,
5441
+ arrayValue: value,
5442
+ onChange: onSelectChange
5443
+ })
5444
+ }, itemType.name);
5445
+ })
5446
+ });
5447
+ }
5448
+ function Selectable(_ref20) {
5449
+ let {
5450
+ title,
5451
+ arrayValue,
5452
+ value,
5453
+ onChange
5454
+ } = _ref20;
5455
+ const checked = !(arrayValue == null ? void 0 : arrayValue.length) || !!(arrayValue == null ? void 0 : arrayValue.find(v => v._key === value));
5456
+ const handleChange = react.useCallback(() => onChange(checked, value), [onChange, checked, value]);
5457
+ return /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
5458
+ gap: 2,
5459
+ align: "flex-start",
5460
+ children: [/* @__PURE__ */jsxRuntime.jsx(ui.Checkbox, {
5461
+ checked,
5462
+ onChange: handleChange
5463
+ }), /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
5464
+ marginTop: 1,
5465
+ onClick: handleChange,
5466
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
5467
+ style: {
5468
+ cursor: "default"
5469
+ },
5470
+ size: 1,
5471
+ children: title
5472
+ })
5473
+ })]
5474
+ });
5475
+ }
5476
+
5477
+ // Strict ESM env, designed to run outside Node.js in envs that provide WebCrypto (deno, browsers, etc)
5478
+
5479
+ function getRandomValues(typedArray) {
5480
+ const crypto = typeof window !== 'undefined' && 'crypto' in window ? window.crypto : globalThis.crypto;
5481
+ if (!crypto || !crypto.getRandomValues) {
5482
+ throw new Error('WebCrypto not available in this environment');
5483
+ }
5484
+ return crypto.getRandomValues(typedArray);
5485
+ }
5486
+ function whatwgRNG() {
5487
+ let length = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : 16;
5488
+ const rnds8 = new Uint8Array(length);
5489
+ getRandomValues(rnds8);
5490
+ return rnds8;
5491
+ }
5492
+ const getByteHexTable = /* @__PURE__ */(() => {
5493
+ let table;
5494
+ return () => {
5495
+ if (table) {
5496
+ return table;
5497
+ }
5498
+ table = [];
5499
+ for (let i = 0; i < 256; ++i) {
5500
+ table[i] = (i + 256).toString(16).substring(1);
5501
+ }
5502
+ return table;
5503
+ };
5504
+ })();
5505
+ function randomKey(length) {
5506
+ const table = getByteHexTable();
5507
+ return whatwgRNG(length).reduce((str, n) => str + table[n], "").slice(0, length);
5508
+ }
5509
+ var __freeze = Object.freeze;
5510
+ var __defProp = Object.defineProperty;
5511
+ var __template = (cooked, raw) => __freeze(__defProp(cooked, "raw", {
5512
+ value: __freeze(raw || cooked.slice())
5513
+ }));
5514
+ var _a;
5515
+ const PteMods = styled__default.default(ui.Box)(_a || (_a = __template(["\n & [data-testid='pt-editor__toolbar-card'] > div > div:last-child {\n display: none;\n }\n & [data-testid='pt-editor'] {\n min-height: 300px;\n }\n & [data-testid='pt-editor'] .pt-inline-object * {\n max-width: 400px;\n }\n"])));
5516
+ function PromptInput(props) {
5517
+ useOnlyInlineBlocks(props);
5518
+ return /* @__PURE__ */jsxRuntime.jsx(PteMods, {
5519
+ children: props.renderDefault(props)
5520
+ });
5521
+ }
5522
+ function useOnlyInlineBlocks(props) {
5523
+ react.useEffect(() => {
5524
+ var _a2;
5525
+ let needsFix = false;
5526
+ const val = ((_a2 = props.value) != null ? _a2 : []).map(block => {
5527
+ if (block._type === "block") {
5528
+ return block;
5529
+ }
5530
+ needsFix = true;
5531
+ return sanity.typed({
5532
+ _key: randomKey(12),
5533
+ _type: "block",
5534
+ level: 0,
5535
+ markDefs: [],
5536
+ style: "normal",
5537
+ children: [block]
5538
+ });
5539
+ });
5540
+ if (needsFix) {
5541
+ props.onChange(sanity.set(val));
5598
5542
  }
5599
- }, [onChange, value, ofItems]);
5600
- return /* @__PURE__ */jsxRuntime.jsx(ui.Stack, {
5601
- space: 2,
5602
- children: ofItems.map(itemType => {
5603
- var _a;
5604
- return /* @__PURE__ */jsxRuntime.jsx(ui.Flex, {
5605
- children: /* @__PURE__ */jsxRuntime.jsx(Selectable, {
5606
- value: itemType.name,
5607
- title: isType(itemType, "block") ? "Text" : (_a = itemType.title) != null ? _a : itemType.name,
5608
- arrayValue: value,
5609
- onChange: onSelectChange
5610
- })
5611
- }, itemType.name);
5612
- })
5543
+ }, []);
5544
+ }
5545
+ function InstructionsArrayField(props) {
5546
+ return props.renderDefault({
5547
+ ...props,
5548
+ title: " "
5613
5549
  });
5614
5550
  }
5615
- function Selectable(_ref21) {
5616
- let {
5617
- title,
5618
- arrayValue,
5551
+ function InstructionsArrayInput(props) {
5552
+ const user = sanity.useCurrentUser();
5553
+ const originalValue = props.value;
5554
+ const originalMembers = props.members;
5555
+ const value = react.useMemo(() => (originalValue != null ? originalValue : []).filter(v => !v.userId || v.userId === (user == null ? void 0 : user.id)), [originalValue, user]);
5556
+ const members = react.useMemo(() => (originalMembers != null ? originalMembers : []).filter(v => {
5557
+ var _a;
5558
+ if (v.kind === "error") {
5559
+ return true;
5560
+ }
5561
+ const value2 = (_a = v == null ? void 0 : v.item) == null ? void 0 : _a.value;
5562
+ return !value2.userId || value2.userId === (user == null ? void 0 : user.id);
5563
+ }), [originalMembers, user]);
5564
+ return props.renderDefault({
5565
+ ...props,
5619
5566
  value,
5620
- onChange
5621
- } = _ref21;
5622
- const checked = !(arrayValue == null ? void 0 : arrayValue.length) || !!(arrayValue == null ? void 0 : arrayValue.find(v => v._key === value));
5623
- const handleChange = react.useCallback(() => onChange(checked, value), [onChange, checked, value]);
5624
- return /* @__PURE__ */jsxRuntime.jsxs(ui.Flex, {
5625
- gap: 2,
5626
- align: "flex-start",
5627
- children: [/* @__PURE__ */jsxRuntime.jsx(ui.Checkbox, {
5628
- checked,
5629
- onChange: handleChange
5630
- }), /* @__PURE__ */jsxRuntime.jsx(ui.Card, {
5631
- marginTop: 1,
5632
- onClick: handleChange,
5633
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
5634
- style: {
5635
- cursor: "default"
5636
- },
5637
- size: 1,
5638
- children: title
5639
- })
5640
- })]
5567
+ members
5568
+ });
5569
+ }
5570
+ function HideReferenceChangedBannerInput(props) {
5571
+ const ref = react.useRef(null);
5572
+ react.useEffect(() => {
5573
+ var _a;
5574
+ const parent = (_a = ref.current) == null ? void 0 : _a.closest('[data-testid="pane-content"]');
5575
+ if (!parent) {
5576
+ return;
5577
+ }
5578
+ const style = document.createElement("style");
5579
+ const parentId = "id-".concat(Math.random()).replace(".", "-");
5580
+ parent.id = parentId;
5581
+ style.innerText = "\n #".concat(parentId, ' [data-testid="reference-changed-banner"] { display: none; }\n ');
5582
+ parent.prepend(style);
5583
+ }, [ref]);
5584
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
5585
+ ref,
5586
+ children: props.renderDefault(props)
5641
5587
  });
5642
5588
  }
5589
+ const contextDocumentSchema = sanity.defineType({
5590
+ type: "document",
5591
+ name: contextDocumentTypeName,
5592
+ title: "AI context",
5593
+ liveEdit: true,
5594
+ icon: icons.TokenIcon,
5595
+ components: {
5596
+ input: HideReferenceChangedBannerInput
5597
+ },
5598
+ fields: [sanity.defineField({
5599
+ type: "string",
5600
+ name: "title",
5601
+ title: "Title"
5602
+ }), sanity.defineField({
5603
+ name: "context",
5604
+ type: "array",
5605
+ title: "Context",
5606
+ of: [sanity.defineArrayMember({
5607
+ type: "block",
5608
+ styles: [{
5609
+ title: "Normal",
5610
+ value: "normal"
5611
+ }],
5612
+ lists: [],
5613
+ marks: {
5614
+ decorators: [],
5615
+ annotations: []
5616
+ }
5617
+ })]
5618
+ })],
5619
+ preview: {
5620
+ select: {
5621
+ title: "title",
5622
+ context: "context"
5623
+ },
5624
+ prepare(_ref21) {
5625
+ let {
5626
+ title,
5627
+ context
5628
+ } = _ref21;
5629
+ var _a;
5630
+ const text = context == null ? void 0 : context.flatMap(block => block == null ? void 0 : block.children).flatMap(child => {
5631
+ var _a2;
5632
+ return (_a2 = child == null ? void 0 : child.text) == null ? void 0 : _a2.split(" ");
5633
+ }).filter(Boolean);
5634
+ const words = (_a = text == null ? void 0 : text.length) != null ? _a : 0;
5635
+ return {
5636
+ title,
5637
+ subtitle: "Words: ".concat(words),
5638
+ media: icons.DocumentTextIcon
5639
+ };
5640
+ }
5641
+ }
5642
+ });
5643
5643
  const fieldReference = sanity.defineType({
5644
5644
  type: "object",
5645
5645
  name: fieldReferenceTypeName,
@@ -6121,193 +6121,60 @@ function excludeComments(type) {
6121
6121
  }
6122
6122
  const instructionForm = [fieldInstructions, instruction, fieldReference, prompt, userInput, promptContext].map(excludeComments);
6123
6123
  const schemaTypes = [...instructionForm, outputFieldType, outputTypeType, assistDocumentSchema, documentInstructionStatus, instructionTask, contextDocumentSchema];
6124
- function useAssistSupported(path, schemaType) {
6125
- return react.useMemo(() => isAssistSupported(schemaType), [schemaType]);
6126
- }
6127
6124
  function useAssistDocumentContextValue(documentId, documentSchemaType) {
6128
6125
  const {
6129
6126
  published,
6130
6127
  draft
6131
6128
  } = sanity.useEditState(sanity.getPublishedId(documentId), documentSchemaType.name, "low");
6132
- const assistableDocumentId = (draft == null ? void 0 : draft._id) || (published == null ? void 0 : published._id) || documentId;
6133
- const documentIsNew = Boolean(!(draft == null ? void 0 : draft._id) && !(published == null ? void 0 : published._id));
6134
- const documentIsAssistable = isDocAssistable(documentSchemaType, published, draft);
6135
- const {
6136
- params
6137
- } = useAiPaneRouter();
6138
- const selectedPath = params[fieldPathParam];
6139
- const {
6140
- openInspector,
6141
- closeInspector,
6142
- inspector,
6143
- onChange: documentOnChange
6144
- } = desk.useDocumentPane();
6145
- const assistDocument = useStudioAssistDocument({
6146
- documentId,
6147
- schemaType: documentSchemaType
6148
- });
6149
- const value = react.useMemo(() => {
6150
- const base = {
6151
- documentId,
6152
- assistableDocumentId,
6153
- documentSchemaType,
6154
- documentIsNew,
6155
- documentIsAssistable,
6156
- openInspector,
6157
- closeInspector,
6158
- inspector,
6159
- documentOnChange,
6160
- selectedPath
6161
- };
6162
- if (!assistDocument) {
6163
- return {
6164
- ...base,
6165
- loading: true,
6166
- assistDocument: void 0
6167
- };
6168
- }
6169
- return {
6170
- ...base,
6171
- loading: false,
6172
- assistDocument
6173
- };
6174
- }, [assistDocument, documentIsAssistable, documentId, assistableDocumentId, documentSchemaType, documentIsNew, openInspector, closeInspector, inspector, documentOnChange, selectedPath]);
6175
- return value;
6176
- }
6177
- function PrivateIcon() {
6178
- return /* @__PURE__ */jsxRuntime.jsx(ui.Tooltip, {
6179
- content: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
6180
- size: 1,
6181
- style: {
6182
- whiteSpace: "nowrap"
6183
- },
6184
- children: "Only visible to you"
6185
- }),
6186
- fallbackPlacements: ["bottom"],
6187
- padding: 2,
6188
- placement: "top",
6189
- portal: true,
6190
- children: /* @__PURE__ */jsxRuntime.jsx(icons.LockIcon, {})
6191
- });
6192
- }
6193
- const ImageContext = react.createContext({});
6194
- function ImageContextProvider(props) {
6195
- var _a, _b;
6196
- const {
6197
- schemaType,
6198
- path,
6199
- value,
6200
- readOnly
6201
- } = props;
6202
- const assetRef = (_a = value == null ? void 0 : value.asset) == null ? void 0 : _a._ref;
6203
- const [assetRefState, setAssetRefState] = react.useState(assetRef);
6204
- const {
6205
- documentId,
6206
- documentSchemaType
6207
- } = useAssistDocumentContext();
6208
- const {
6209
- config,
6210
- status
6211
- } = useAiAssistanceConfig();
6212
- const apiClient = useApiClient(config == null ? void 0 : config.__customApiClient);
6213
- const {
6214
- generateCaption
6215
- } = useGenerateCaption(apiClient);
6216
- const {
6217
- isSyncing
6218
- } = sanity.useSyncState(publicId(documentId), documentSchemaType.name);
6219
- const router = desk.usePaneRouter();
6220
- const isShowingOlderRevision = !!((_b = router.params) == null ? void 0 : _b.rev);
6221
- react.useEffect(() => {
6222
- const descriptionField = getDescriptionFieldOption(schemaType);
6223
- if (assetRef && documentId && descriptionField && assetRef !== assetRefState && !isSyncing && !isShowingOlderRevision && !readOnly) {
6224
- setAssetRefState(assetRef);
6225
- if (canUseAssist(status)) {
6226
- generateCaption({
6227
- path: sanity.pathToString([...path, descriptionField]),
6228
- documentId
6229
- });
6230
- }
6129
+ const assistableDocumentId = (draft == null ? void 0 : draft._id) || (published == null ? void 0 : published._id) || documentId;
6130
+ const documentIsNew = Boolean(!(draft == null ? void 0 : draft._id) && !(published == null ? void 0 : published._id));
6131
+ const documentIsAssistable = isDocAssistable(documentSchemaType, published, draft);
6132
+ const {
6133
+ params
6134
+ } = useAiPaneRouter();
6135
+ const selectedPath = params[fieldPathParam];
6136
+ const {
6137
+ openInspector,
6138
+ closeInspector,
6139
+ inspector,
6140
+ onChange: documentOnChange
6141
+ } = desk.useDocumentPane();
6142
+ const assistDocument = useStudioAssistDocument({
6143
+ documentId,
6144
+ schemaType: documentSchemaType
6145
+ });
6146
+ const value = react.useMemo(() => {
6147
+ const base = {
6148
+ documentId,
6149
+ assistableDocumentId,
6150
+ documentSchemaType,
6151
+ documentIsNew,
6152
+ documentIsAssistable,
6153
+ openInspector,
6154
+ closeInspector,
6155
+ inspector,
6156
+ documentOnChange,
6157
+ selectedPath
6158
+ };
6159
+ if (!assistDocument) {
6160
+ return {
6161
+ ...base,
6162
+ loading: true,
6163
+ assistDocument: void 0
6164
+ };
6231
6165
  }
6232
- }, [schemaType, path, assetRef, assetRefState, documentId, generateCaption, isSyncing, status, readOnly, isShowingOlderRevision]);
6233
- const context = react.useMemo(() => {
6234
- const descriptionField = getDescriptionFieldOption(schemaType);
6235
- const imageInstructionField = getImageInstructionFieldOption(schemaType);
6236
6166
  return {
6237
- imageDescriptionPath: descriptionField ? sanity.pathToString([...path, descriptionField]) : void 0,
6238
- imageInstructionPath: imageInstructionField ? sanity.pathToString([...path, imageInstructionField]) : void 0,
6239
- assetRef
6167
+ ...base,
6168
+ loading: false,
6169
+ assistDocument
6240
6170
  };
6241
- }, [schemaType, path, assetRef]);
6242
- return /* @__PURE__ */jsxRuntime.jsx(ImageContext.Provider, {
6243
- value: context,
6244
- children: props.renderDefault(props)
6245
- });
6171
+ }, [assistDocument, documentIsAssistable, documentId, assistableDocumentId, documentSchemaType, documentIsNew, openInspector, closeInspector, inspector, documentOnChange, selectedPath]);
6172
+ return value;
6246
6173
  }
6247
- function node$3(node2) {
6248
- return node2;
6174
+ function useAssistSupported(path, schemaType) {
6175
+ return react.useMemo(() => isAssistSupported(schemaType), [schemaType]);
6249
6176
  }
6250
- const generateCaptionsActions = {
6251
- name: "sanity-assist-generate-captions",
6252
- useAction(props) {
6253
- const pathKey = usePathKey(props.path);
6254
- const {
6255
- openInspector
6256
- } = desk.useDocumentPane();
6257
- const {
6258
- config,
6259
- status
6260
- } = useAiAssistanceConfig();
6261
- const apiClient = useApiClient(config == null ? void 0 : config.__customApiClient);
6262
- const {
6263
- generateCaption,
6264
- loading
6265
- } = useGenerateCaption(apiClient);
6266
- const imageContext = react.useContext(ImageContext);
6267
- if (imageContext && pathKey === (imageContext == null ? void 0 : imageContext.imageDescriptionPath)) {
6268
- const {
6269
- documentId
6270
- } = useAssistDocumentContext();
6271
- return react.useMemo(() => {
6272
- return node$3({
6273
- type: "action",
6274
- icon: loading ? () => /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
6275
- style: {
6276
- height: 17
6277
- },
6278
- children: /* @__PURE__ */jsxRuntime.jsx(ui.Spinner, {
6279
- style: {
6280
- transform: "translateY(6px)"
6281
- }
6282
- })
6283
- }) : icons.ImageIcon,
6284
- title: "Generate image description",
6285
- onAction: () => {
6286
- if (loading) {
6287
- return;
6288
- }
6289
- if (!canUseAssist(status)) {
6290
- openInspector(aiInspectorId, {
6291
- [fieldPathParam]: pathKey,
6292
- [instructionParam]: void 0
6293
- });
6294
- return;
6295
- }
6296
- generateCaption({
6297
- path: pathKey,
6298
- documentId: documentId != null ? documentId : ""
6299
- });
6300
- },
6301
- renderAsButton: true,
6302
- disabled: loading,
6303
- hidden: !imageContext.assetRef
6304
- });
6305
- }, [generateCaption, pathKey, documentId, loading, imageContext, status, openInspector]);
6306
- }
6307
- return void 0;
6308
- }
6309
- };
6310
- function node$2(node2) {
6177
+ function node$3(node2) {
6311
6178
  return node2;
6312
6179
  }
6313
6180
  const translateActions = {
@@ -6355,7 +6222,7 @@ const translateActions = {
6355
6222
  return void 0;
6356
6223
  }
6357
6224
  const title = path.length ? "Translate" : "Translate document";
6358
- return node$2({
6225
+ return node$3({
6359
6226
  type: "action",
6360
6227
  icon: translationApi.loading ? () => /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
6361
6228
  style: {
@@ -6389,7 +6256,7 @@ const translateActions = {
6389
6256
  isDocAssistable: documentIsAssistable != null ? documentIsAssistable : false,
6390
6257
  task: fieldTranslate.openFieldTranslation
6391
6258
  });
6392
- const translateFieldsAction = react.useMemo(() => fieldTransEnabled ? node$2({
6259
+ const translateFieldsAction = react.useMemo(() => fieldTransEnabled ? node$3({
6393
6260
  type: "action",
6394
6261
  icon: fieldTranslate.translationLoading ? () => /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
6395
6262
  style: {
@@ -6423,7 +6290,7 @@ const translateActions = {
6423
6290
  if (!(status == null ? void 0 : status.initialized)) {
6424
6291
  return void 0;
6425
6292
  }
6426
- return node$2({
6293
+ return node$3({
6427
6294
  type: "group",
6428
6295
  icon: () => null,
6429
6296
  title: "Translation",
@@ -6435,6 +6302,123 @@ const translateActions = {
6435
6302
  return void 0;
6436
6303
  }
6437
6304
  };
6305
+ const ImageContext = react.createContext({});
6306
+ function ImageContextProvider(props) {
6307
+ var _a, _b;
6308
+ const {
6309
+ schemaType,
6310
+ path,
6311
+ value,
6312
+ readOnly
6313
+ } = props;
6314
+ const assetRef = (_a = value == null ? void 0 : value.asset) == null ? void 0 : _a._ref;
6315
+ const [assetRefState, setAssetRefState] = react.useState(assetRef);
6316
+ const {
6317
+ documentId,
6318
+ documentSchemaType
6319
+ } = useAssistDocumentContext();
6320
+ const {
6321
+ config,
6322
+ status
6323
+ } = useAiAssistanceConfig();
6324
+ const apiClient = useApiClient(config == null ? void 0 : config.__customApiClient);
6325
+ const {
6326
+ generateCaption
6327
+ } = useGenerateCaption(apiClient);
6328
+ const {
6329
+ isSyncing
6330
+ } = sanity.useSyncState(publicId(documentId), documentSchemaType.name);
6331
+ const router = desk.usePaneRouter();
6332
+ const isShowingOlderRevision = !!((_b = router.params) == null ? void 0 : _b.rev);
6333
+ react.useEffect(() => {
6334
+ const descriptionField = getDescriptionFieldOption(schemaType);
6335
+ if (assetRef && documentId && descriptionField && assetRef !== assetRefState && !isSyncing && !isShowingOlderRevision && !readOnly) {
6336
+ setAssetRefState(assetRef);
6337
+ if (canUseAssist(status)) {
6338
+ generateCaption({
6339
+ path: sanity.pathToString([...path, descriptionField]),
6340
+ documentId
6341
+ });
6342
+ }
6343
+ }
6344
+ }, [schemaType, path, assetRef, assetRefState, documentId, generateCaption, isSyncing, status, readOnly, isShowingOlderRevision]);
6345
+ const context = react.useMemo(() => {
6346
+ const descriptionField = getDescriptionFieldOption(schemaType);
6347
+ const imageInstructionField = getImageInstructionFieldOption(schemaType);
6348
+ return {
6349
+ imageDescriptionPath: descriptionField ? sanity.pathToString([...path, descriptionField]) : void 0,
6350
+ imageInstructionPath: imageInstructionField ? sanity.pathToString([...path, imageInstructionField]) : void 0,
6351
+ assetRef
6352
+ };
6353
+ }, [schemaType, path, assetRef]);
6354
+ return /* @__PURE__ */jsxRuntime.jsx(ImageContext.Provider, {
6355
+ value: context,
6356
+ children: props.renderDefault(props)
6357
+ });
6358
+ }
6359
+ function node$2(node2) {
6360
+ return node2;
6361
+ }
6362
+ const generateCaptionsActions = {
6363
+ name: "sanity-assist-generate-captions",
6364
+ useAction(props) {
6365
+ const pathKey = usePathKey(props.path);
6366
+ const {
6367
+ openInspector
6368
+ } = desk.useDocumentPane();
6369
+ const {
6370
+ config,
6371
+ status
6372
+ } = useAiAssistanceConfig();
6373
+ const apiClient = useApiClient(config == null ? void 0 : config.__customApiClient);
6374
+ const {
6375
+ generateCaption,
6376
+ loading
6377
+ } = useGenerateCaption(apiClient);
6378
+ const imageContext = react.useContext(ImageContext);
6379
+ if (imageContext && pathKey === (imageContext == null ? void 0 : imageContext.imageDescriptionPath)) {
6380
+ const {
6381
+ documentId
6382
+ } = useAssistDocumentContext();
6383
+ return react.useMemo(() => {
6384
+ return node$2({
6385
+ type: "action",
6386
+ icon: loading ? () => /* @__PURE__ */jsxRuntime.jsx(ui.Box, {
6387
+ style: {
6388
+ height: 17
6389
+ },
6390
+ children: /* @__PURE__ */jsxRuntime.jsx(ui.Spinner, {
6391
+ style: {
6392
+ transform: "translateY(6px)"
6393
+ }
6394
+ })
6395
+ }) : icons.ImageIcon,
6396
+ title: "Generate image description",
6397
+ onAction: () => {
6398
+ if (loading) {
6399
+ return;
6400
+ }
6401
+ if (!canUseAssist(status)) {
6402
+ openInspector(aiInspectorId, {
6403
+ [fieldPathParam]: pathKey,
6404
+ [instructionParam]: void 0
6405
+ });
6406
+ return;
6407
+ }
6408
+ generateCaption({
6409
+ path: pathKey,
6410
+ documentId: documentId != null ? documentId : ""
6411
+ });
6412
+ },
6413
+ renderAsButton: true,
6414
+ disabled: loading,
6415
+ hidden: !imageContext.assetRef
6416
+ });
6417
+ }, [generateCaption, pathKey, documentId, loading, imageContext, status, openInspector]);
6418
+ }
6419
+ return void 0;
6420
+ }
6421
+ };
6438
6422
  function node$1(node2) {
6439
6423
  return node2;
6440
6424
  }
@@ -6486,6 +6470,22 @@ const generateImagActions = {
6486
6470
  return void 0;
6487
6471
  }
6488
6472
  };
6473
+ function PrivateIcon() {
6474
+ return /* @__PURE__ */jsxRuntime.jsx(ui.Tooltip, {
6475
+ content: /* @__PURE__ */jsxRuntime.jsx(ui.Text, {
6476
+ size: 1,
6477
+ style: {
6478
+ whiteSpace: "nowrap"
6479
+ },
6480
+ children: "Only visible to you"
6481
+ }),
6482
+ fallbackPlacements: ["bottom"],
6483
+ padding: 2,
6484
+ placement: "top",
6485
+ portal: true,
6486
+ children: /* @__PURE__ */jsxRuntime.jsx(icons.LockIcon, {})
6487
+ });
6488
+ }
6489
6489
  function node(node2) {
6490
6490
  return node2;
6491
6491
  }
@@ -6583,14 +6583,14 @@ const assistFieldActions = {
6583
6583
  type: "group",
6584
6584
  icon: () => null,
6585
6585
  title: "Run instructions",
6586
- children: [...(instructions == null ? void 0 : instructions.map(instruction => instructionItem({
6586
+ children: [...((instructions == null ? void 0 : instructions.map(instruction => instructionItem({
6587
6587
  instruction,
6588
6588
  isPrivate: Boolean(instruction.userId && instruction.userId === (currentUser == null ? void 0 : currentUser.id)),
6589
6589
  onInstructionAction,
6590
6590
  hidden: isHidden,
6591
6591
  documentIsNew: !!documentIsNew,
6592
6592
  assistSupported
6593
- }))), imageCaptionAction, imageGenAction].filter(a => !!a),
6593
+ }))) || []), imageCaptionAction, imageGenAction].filter(a => !!a),
6594
6594
  expanded: true
6595
6595
  }) : void 0;
6596
6596
  }, [instructions, currentUser == null ? void 0 : currentUser.id, onInstructionAction, isHidden, documentIsNew, assistSupported, imageCaptionAction, translateAction, imageGenAction]);