@sanity/assist 4.3.1 → 4.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -35,7 +35,7 @@
35
35
  - [Adding translation actions to fields](#adding-translation-actions-to-fields)
36
36
  - [Translation style guide](#translation-style-guide)
37
37
  - [Custom field actions](#custom-field-actions)
38
- - [useFieldActions](#usefieldaction)
38
+ - [useExampleFieldActions](#usefieldaction)
39
39
  - [Define helpers](#define-helpers)
40
40
  - [useUserInput](#useuserinput)
41
41
  - [License](#license)
@@ -949,40 +949,59 @@ assist({
949
949
  <img width="513" alt="Field action menu with custom actions" src="https://github.com/user-attachments/assets/c613f692-4983-4acc-a8c2-8fb60294682a" />
950
950
 
951
951
  To incorporate [Agent Actions](https://www.sanity.io/docs/agent-actions?utm_source=github.com&utm_medium=organic_social&utm_campaign=ai-assist&utm_content=)
952
- or other custom actions into the AI Assist document and field action menus, use `fieldActions` plugin config:
952
+ or other custom actions into the AI Assist document and field action menus, use `fieldActions` plugin config.
953
+
954
+ Because of react hook linting, we recommend defining the `useExampleFieldActions` outside the plugin config:
953
955
 
954
956
  ```ts
955
- assist({
956
- fieldActions: {
957
- title: 'Custom actions',
958
- useFieldActions: (props: AssistFieldActionProps) => {
959
- return useMemo(() => [
960
- defineAssistFieldAction({
961
- title: 'Do something',
962
- icon: ActionIcon,
963
- onAction: async () => {
964
- // perform an (async) action
965
- // errors will be caught and displayed in a toast
966
- // until the action completes or fails, AI Assist "presence" will show up on the top of the document
967
- },
968
- })], [])
969
- }
970
- }
957
+ //sanity.config.ts
958
+ import {defineConfig} from 'sanity'
959
+ import {assist, type AssistFieldActionProps, defineAssistFieldAction} from '@sanity/assist'
960
+
961
+ function useExampleFieldActions(props: AssistFieldActionProps) {
962
+ return useMemo(() => [
963
+ defineAssistFieldAction({
964
+ title: 'Do something',
965
+ icon: ActionIcon,
966
+ onAction: async () => {
967
+ // perform an (async) action
968
+ // errors will be caught and displayed in a toast
969
+ // until the action completes or fails, AI Assist "presence" will show up on the top of the document
970
+ },
971
+ })], [])
972
+ }
973
+
974
+ export default defineConfig({
975
+ //...
976
+ plugins: [
977
+ //...other plugins
978
+ assist({
979
+ fieldActions: {
980
+ title: 'Custom actions',
981
+ useExampleFieldActions
982
+ }
983
+ })
984
+ ]
971
985
  })
972
986
  ```
973
987
 
974
- ### `useFieldActions`
988
+ ### `useExampleFieldActions`
975
989
 
976
- `useFieldActions` is called for the document itself and for all fields within it. It can call React hooks.
990
+ `useExampleFieldActions` is called for the document itself and for all fields within it. It can call React hooks.
977
991
  Actions returned by the hook will be added to the corresponding document or field menu.
978
992
 
979
- It is recommended to wrap the returned actions in `useMemo`.
993
+ It is recommended to wrap the returned actions in `useMemo`. The returned array can contain `undefined` values.
994
+ These will be filtered out.
995
+
980
996
 
981
997
  See TSDocs for [AssistFieldActionProps](./src/fieldActions/customFieldActions.tsx) for details on how each
982
998
  prop can be used to parameterize Agent Actions on sanity client.
983
999
 
984
1000
  #### Agent Action examples
985
1001
 
1002
+ Below are some examples of agent action integration.
1003
+ For more, see [HOW-TO_USE](../studio/examples/agentActions/HOW-TO-USE.md)
1004
+
986
1005
  ##### Fix spelling
987
1006
 
988
1007
  The following example adds a "Fix spelling" action to all fields and the document itself.
@@ -991,49 +1010,44 @@ It will fix spelling mistakes for the field it is invoked for (and all child fie
991
1010
  by calling `client.agent.action.transform`.
992
1011
 
993
1012
  ```ts
994
- assist({
995
- fieldActions: {
996
- title: 'Custom actions',
997
- useFieldActions: (props) => {
998
- const {
999
- documentSchemaType,
1000
- schemaId,
1001
- getDocumentValue,
1002
- getConditionalPaths,
1003
- documentIdForAction,
1004
- path,
1005
- } = props
1006
- const client = useClient({apiVersion: 'vX'})
1007
- return useMemo(() => {
1008
- return [
1009
- defineAssistFieldAction({
1010
- title: 'Fix spelling',
1011
- icon: TranslateIcon,
1012
- onAction: async () => {
1013
- await client.agent.action.transform({
1014
- schemaId,
1015
- documentId: documentIdForAction,
1016
- instruction: 'Fix any spelling mistakes',
1017
- instructionParams: {field: {type: 'field', path}},
1018
- // no need to send path for document actions
1019
- target: path.length ? {path} : undefined,
1020
- conditionalPaths: {paths: getConditionalPaths()},
1021
- })
1022
- },
1023
- }),
1024
- ]
1025
- }, [
1026
- client,
1027
- documentSchemaType,
1028
- schemaId,
1029
- getDocumentValue,
1030
- getConditionalPaths,
1031
- documentIdForAction,
1032
- path,
1033
- ])
1034
- },
1035
- },
1036
- })
1013
+ function useExampleFieldActions(props: AssistFieldActionProps) {
1014
+ const {
1015
+ documentSchemaType,
1016
+ schemaId,
1017
+ getDocumentValue,
1018
+ getConditionalPaths,
1019
+ documentIdForAction,
1020
+ path,
1021
+ } = props
1022
+ const client = useClient({apiVersion: 'vX'})
1023
+ return useMemo(() => {
1024
+ return [
1025
+ defineAssistFieldAction({
1026
+ title: 'Fix spelling',
1027
+ icon: TranslateIcon,
1028
+ onAction: async () => {
1029
+ await client.agent.action.transform({
1030
+ schemaId,
1031
+ documentId: documentIdForAction,
1032
+ instruction: 'Fix any spelling mistakes',
1033
+ instructionParams: {field: {type: 'field', path}},
1034
+ // no need to send path for document actions
1035
+ target: path.length ? {path} : undefined,
1036
+ conditionalPaths: {paths: getConditionalPaths()},
1037
+ })
1038
+ },
1039
+ }),
1040
+ ]
1041
+ }, [
1042
+ client,
1043
+ documentSchemaType,
1044
+ schemaId,
1045
+ getDocumentValue,
1046
+ getConditionalPaths,
1047
+ documentIdForAction,
1048
+ path,
1049
+ ])
1050
+ }
1037
1051
  ```
1038
1052
 
1039
1053
  ##### Fill field (contextually aware)
@@ -1047,44 +1061,41 @@ The action will:
1047
1061
  - output to the field the action started from (`target.path`)
1048
1062
 
1049
1063
  ```ts
1050
- assist({
1051
- fieldActions: {
1052
- title: 'Custom actions',
1053
- useFieldActions: (props) => {
1054
- const {
1055
- documentSchemaType,
1056
- actionType,
1057
- schemaId,
1058
- getDocumentValue,
1059
- getConditionalPaths,
1060
- documentIdForAction,
1061
- path,
1062
- schemaType,
1063
- } = props
1064
-
1065
- // hook usage has to happen outside onAction, so preassemble state in useFieldActions and pass to useMemo
1066
- const client = useClient({apiVersion: 'vX'})
1067
-
1068
- return useMemo(() => {
1069
- if (actionType === 'document') {
1070
- // in this case we dont want a document action
1071
- return []
1072
- }
1064
+ function useExampleFieldActions(props: AssistFieldActionProps) {
1065
+ const {
1066
+ documentSchemaType,
1067
+ actionType,
1068
+ schemaId,
1069
+ getDocumentValue,
1070
+ getConditionalPaths,
1071
+ documentIdForAction,
1072
+ path,
1073
+ schemaType,
1074
+ } = props
1075
+
1076
+ // hook usage has to happen outside onAction, so preassemble state in useExampleFieldActions and pass to useMemo
1077
+ const client = useClient({apiVersion: 'vX'})
1078
+
1079
+ return useMemo(() => {
1080
+ if (actionType === 'document') {
1081
+ // in this case we dont want a document action
1082
+ return []
1083
+ }
1073
1084
 
1074
- return [
1075
- defineAssistFieldAction({
1076
- title: 'Fill field',
1077
- icon: EditIcon,
1078
- onAction: async () => {
1079
- await client.agent.action.generate({
1080
- schemaId,
1081
- targetDocument: {
1082
- operation: 'createIfNotExists',
1083
- _id: documentIdForAction,
1084
- _type: documentSchemaType.name,
1085
- initialValues: getDocumentValue(),
1086
- },
1087
- instruction: `
1085
+ return [
1086
+ defineAssistFieldAction({
1087
+ title: 'Fill field',
1088
+ icon: EditIcon,
1089
+ onAction: async () => {
1090
+ await client.agent.action.generate({
1091
+ schemaId,
1092
+ targetDocument: {
1093
+ operation: 'createIfNotExists',
1094
+ _id: documentIdForAction,
1095
+ _type: documentSchemaType.name,
1096
+ initialValues: getDocumentValue(),
1097
+ },
1098
+ instruction: `
1088
1099
  We are generating a new value for a document field.
1089
1100
  The document type is ${documentSchemaType.name}, and the document type title is ${documentSchemaType.title}
1090
1101
  The document language is: "$lang" (use en-US if unspecified)
@@ -1099,35 +1110,33 @@ The action will:
1099
1110
  Generate a new field value. The new value should be relevant to the document type and context.
1100
1111
  Keep it interesting. Generate using the document language.
1101
1112
  `,
1102
- instructionParams: {
1103
- doc: {type: 'document'},
1104
- field: {type: 'field', path},
1105
- lang: {type: 'field', path: ['language']},
1106
- },
1107
- target: {
1108
- path,
1109
- },
1110
- conditionalPaths: {
1111
- paths: getConditionalPaths(),
1112
- },
1113
- })
1113
+ instructionParams: {
1114
+ doc: {type: 'document'},
1115
+ field: {type: 'field', path},
1116
+ lang: {type: 'field', path: ['language']},
1114
1117
  },
1115
- }),
1116
- ]
1117
- }, [
1118
- client,
1119
- documentSchemaType,
1120
- schemaId,
1121
- getDocumentValue,
1122
- getConditionalPaths,
1123
- documentIdForAction,
1124
- actionType,
1125
- path,
1126
- schemaType,
1127
- ])
1128
- },
1129
- },
1130
- })
1118
+ target: {
1119
+ path,
1120
+ },
1121
+ conditionalPaths: {
1122
+ paths: getConditionalPaths(),
1123
+ },
1124
+ })
1125
+ },
1126
+ }),
1127
+ ]
1128
+ }, [
1129
+ client,
1130
+ documentSchemaType,
1131
+ schemaId,
1132
+ getDocumentValue,
1133
+ getConditionalPaths,
1134
+ documentIdForAction,
1135
+ actionType,
1136
+ path,
1137
+ schemaType,
1138
+ ])
1139
+ }
1131
1140
  ```
1132
1141
 
1133
1142
  ### Define helpers
@@ -1136,7 +1145,7 @@ The action will:
1136
1145
 
1137
1146
  Adds a single action that will appear in the document/field action menu.
1138
1147
 
1139
- `onAction` _cannot_ call hooks. If state from hook is needed, it should be pre-assembled by `useFieldActions`
1148
+ `onAction` _cannot_ call hooks. If state from hook is needed, it should be pre-assembled by `useExampleFieldActions`
1140
1149
 
1141
1150
  ```ts
1142
1151
  defineAssistFieldAction({
@@ -1151,10 +1160,12 @@ defineAssistFieldAction({
1151
1160
  #### `defineAssistFieldActionGroup`
1152
1161
 
1153
1162
  Adds a group to hold one or more actions (or nested groups).
1163
+ `children` can contain `undefined` values. These will be filtered out.
1164
+ A group that has an empty `children` array (or only undefined values) will be filtered out.
1154
1165
 
1155
- By default, any actions returned by `useFieldActions` will be grouped under `title`.
1166
+ By default, any actions returned by `useExampleFieldActions` will be grouped under `title`.
1156
1167
  ```ts
1157
- useFieldActions: (props) => {
1168
+ function useExampleFieldActions(props: AssistFieldActionProps) {
1158
1169
  return [
1159
1170
  defineAssistFieldAction({/* ... */}),
1160
1171
  defineAssistFieldActionGroup({
@@ -1167,15 +1178,14 @@ useFieldActions: (props) => {
1167
1178
  }
1168
1179
  ```
1169
1180
 
1170
- #### Only groups in `useFieldActions`
1171
- If `useFieldActions` _only_ returns groups, the default wrapper group will be omitted. This allows full control over each group title.
1181
+ #### Only groups in `useExampleFieldActions`
1182
+ If `useExampleFieldActions` _only_ returns groups, the default wrapper group will be omitted. This allows full control over each group title.
1172
1183
 
1173
1184
  #### `defineFieldActionDivider`
1174
1185
  Adds a divider between actions or groups. Takes no arguments:
1175
1186
 
1176
1187
  ```ts
1177
-
1178
- useFieldActions: (props) => {
1188
+ function useExampleFieldActions(props: AssistFieldActionProps) {
1179
1189
  return useMemo(() => [
1180
1190
  defineAssistFieldAction({/* ... */}),
1181
1191
  defineFieldActionDivider(),
@@ -1198,45 +1208,41 @@ When the user completes the dialog, the user inputted text will be available (or
1198
1208
 
1199
1209
 
1200
1210
  ```ts
1201
- ({
1202
- fieldActions: {
1203
- title: 'Custom actions',
1204
- useFieldActions: (props) => {
1205
- const getUserInput = useUserInput()
1206
-
1207
- return useMemo(
1208
- () => [
1209
- defineAssistFieldAction({
1210
- title: 'Do something with user input',
1211
- onAction: async () => {
1212
- const inputResult = await getUserInput({
1213
- title: 'What do you want to do?', // dialog title
1214
- inputs: [
1215
- {
1216
- id: 'topic',
1217
- title: 'Topic',
1218
- },
1219
- {
1220
- id: 'facts',
1221
- title: 'Facts',
1222
- description: 'Provide additional facts that will be used by the action',
1223
- },
1224
- ],
1225
- })
1226
- if (!inputResult) {
1227
- return // user closed the dialog
1228
- }
1229
-
1230
- //use the result from each input
1231
- //const [{result: topic}, {result: facts}] = inputResult
1232
- },
1233
- }),
1234
- ],
1235
- [getUserInput],
1236
- )
1237
- },
1238
- },
1239
- })
1211
+
1212
+ function useExampleFieldActions(props: AssistFieldActionProps) {
1213
+ const getUserInput = useUserInput()
1214
+
1215
+ return useMemo(
1216
+ () => [
1217
+ defineAssistFieldAction({
1218
+ title: 'Do something with user input',
1219
+ onAction: async () => {
1220
+ const inputResult = await getUserInput({
1221
+ title: 'What do you want to do?', // dialog title
1222
+ inputs: [
1223
+ {
1224
+ id: 'topic',
1225
+ title: 'Topic',
1226
+ },
1227
+ {
1228
+ id: 'facts',
1229
+ title: 'Facts',
1230
+ description: 'Provide additional facts that will be used by the action',
1231
+ },
1232
+ ],
1233
+ })
1234
+ if (!inputResult) {
1235
+ return // user closed the dialog
1236
+ }
1237
+
1238
+ //use the result from each input
1239
+ //const [{result: topic}, {result: facts}] = inputResult
1240
+ },
1241
+ }),
1242
+ ],
1243
+ [getUserInput],
1244
+ )
1245
+ }
1240
1246
  ```
1241
1247
 
1242
1248
  ## Caveats
package/dist/index.d.mts CHANGED
@@ -78,7 +78,11 @@ export declare type AssistFieldActionGroup = Omit<
78
78
  DocumentFieldActionGroup,
79
79
  'renderAsButton' | 'expanded' | 'children'
80
80
  > & {
81
- children: AssistFieldActionNode[]
81
+ /**
82
+ * `children` can include undefined entries in the action array. These will be filtered out.
83
+ * If the group has no defined children, the group will also be filtered out.
84
+ */
85
+ children: (AssistFieldActionNode | undefined)[]
82
86
  }
83
87
 
84
88
  export declare type AssistFieldActionItem = Omit<
@@ -153,6 +157,8 @@ export declare interface AssistFieldActionProps {
153
157
  * },
154
158
  * //...
155
159
  * })
160
+ *
161
+ * ```
156
162
  */
157
163
  schemaId: string
158
164
  /**
@@ -201,6 +207,15 @@ export declare interface AssistFieldActionProps {
201
207
  * ```
202
208
  */
203
209
  schemaType: SchemaType_2
210
+ /**
211
+ * Schema type of the parent field or array item holding this field.
212
+ *
213
+ * This can be undefined if the action was unable to resolve the parent type is excluded from AI Assist.
214
+ *
215
+ * @see schemaType
216
+ * @see documentSchemaType
217
+ */
218
+ parentSchemaType?: SchemaType_2
204
219
  }
205
220
 
206
221
  export declare interface AssistOptions {
@@ -223,7 +238,10 @@ declare interface AssistPluginConfig {
223
238
  assist?: AssistConfig
224
239
  fieldActions?: {
225
240
  title?: string
226
- useFieldActions?: (props: AssistFieldActionProps) => AssistFieldActionNode[]
241
+ /**
242
+ * The returned array can include `undefined` entries in the action array. These will be filtered out.
243
+ */
244
+ useFieldActions?: (props: AssistFieldActionProps) => (AssistFieldActionNode | undefined)[]
227
245
  }
228
246
  /**
229
247
  * @internal
@@ -525,7 +543,7 @@ declare interface PresetInstruction {
525
543
  prompt?: PromptTextBlock[]
526
544
  title?: string
527
545
  /**
528
- * String key from @sanity/icons IconMap
546
+ * String key from `@sanity/icons` IconMap
529
547
  */
530
548
  icon?: string
531
549
  /**
package/dist/index.d.ts CHANGED
@@ -78,7 +78,11 @@ export declare type AssistFieldActionGroup = Omit<
78
78
  DocumentFieldActionGroup,
79
79
  'renderAsButton' | 'expanded' | 'children'
80
80
  > & {
81
- children: AssistFieldActionNode[]
81
+ /**
82
+ * `children` can include undefined entries in the action array. These will be filtered out.
83
+ * If the group has no defined children, the group will also be filtered out.
84
+ */
85
+ children: (AssistFieldActionNode | undefined)[]
82
86
  }
83
87
 
84
88
  export declare type AssistFieldActionItem = Omit<
@@ -153,6 +157,8 @@ export declare interface AssistFieldActionProps {
153
157
  * },
154
158
  * //...
155
159
  * })
160
+ *
161
+ * ```
156
162
  */
157
163
  schemaId: string
158
164
  /**
@@ -201,6 +207,15 @@ export declare interface AssistFieldActionProps {
201
207
  * ```
202
208
  */
203
209
  schemaType: SchemaType_2
210
+ /**
211
+ * Schema type of the parent field or array item holding this field.
212
+ *
213
+ * This can be undefined if the action was unable to resolve the parent type is excluded from AI Assist.
214
+ *
215
+ * @see schemaType
216
+ * @see documentSchemaType
217
+ */
218
+ parentSchemaType?: SchemaType_2
204
219
  }
205
220
 
206
221
  export declare interface AssistOptions {
@@ -223,7 +238,10 @@ declare interface AssistPluginConfig {
223
238
  assist?: AssistConfig
224
239
  fieldActions?: {
225
240
  title?: string
226
- useFieldActions?: (props: AssistFieldActionProps) => AssistFieldActionNode[]
241
+ /**
242
+ * The returned array can include `undefined` entries in the action array. These will be filtered out.
243
+ */
244
+ useFieldActions?: (props: AssistFieldActionProps) => (AssistFieldActionNode | undefined)[]
227
245
  }
228
246
  /**
229
247
  * @internal
@@ -525,7 +543,7 @@ declare interface PresetInstruction {
525
543
  prompt?: PromptTextBlock[]
526
544
  title?: string
527
545
  /**
528
- * String key from @sanity/icons IconMap
546
+ * String key from `@sanity/icons` IconMap
529
547
  */
530
548
  icon?: string
531
549
  /**
package/dist/index.esm.js CHANGED
@@ -211,6 +211,9 @@ function getPathKey(path) {
211
211
  function getInstructionTitle(instruction2) {
212
212
  return instruction2?.title ?? "Untitled";
213
213
  }
214
+ function isDefined(t) {
215
+ return t != null;
216
+ }
214
217
  function isPortableTextArray(type) {
215
218
  return type.of.find((t) => isType(t, "block"));
216
219
  }
@@ -397,6 +400,12 @@ function getTypeIcon(schemaType) {
397
400
  }
398
401
  return isType(schemaType, "slug") ? LinkIcon : isType(schemaType, "image") ? ImageIcon : schemaType.jsonType === "array" && isPortableTextArray(schemaType) ? BlockContentIcon : schemaType.jsonType === "array" ? OlistIcon : schemaType.jsonType === "object" ? BlockquoteIcon : schemaType.jsonType === "string" ? StringIcon : DocumentIcon;
399
402
  }
403
+ function asFieldRefsByTypePath(fieldRefs) {
404
+ return fieldRefs.reduce(
405
+ (acc, ref) => ({ ...acc, [ref.key]: ref }),
406
+ {}
407
+ );
408
+ }
400
409
  function getFieldRefsWithDocument(schemaType) {
401
410
  const fields = getFieldRefs(schemaType);
402
411
  return [
@@ -1026,7 +1035,7 @@ function useAssistDocumentContextValue(documentId, documentType) {
1026
1035
  } = useDocumentPane(), { draft, published, version } = editState || {}, assistableDocumentId = selectedReleaseId ? getVersionId(documentId, selectedReleaseId) : documentSchemaType.liveEdit ? documentId : getDraftId(documentId), documentIsNew = selectedReleaseId ? !version?._id : !draft?._id && !published?._id, documentIsAssistable = selectedReleaseId ? !!version : isDocAssistable(documentSchemaType, published, draft), { params } = useAiPaneRouter(), selectedPath = params[fieldPathParam], assistDocument = useStudioAssistDocument({
1027
1036
  documentId: assistableDocumentId,
1028
1037
  schemaType: documentSchemaType
1029
- }), { syntheticTasks, addSyntheticTask, removeSyntheticTask } = useSyntheticTasks(assistableDocumentId);
1038
+ }), { syntheticTasks, addSyntheticTask, removeSyntheticTask } = useSyntheticTasks(assistableDocumentId), fieldRefs = getFieldRefs(documentSchemaType), fieldRefsByTypePath = asFieldRefsByTypePath(fieldRefs);
1030
1039
  return useMemo(() => {
1031
1040
  const base = {
1032
1041
  assistableDocumentId,
@@ -1040,7 +1049,9 @@ function useAssistDocumentContextValue(documentId, documentType) {
1040
1049
  selectedPath,
1041
1050
  syntheticTasks,
1042
1051
  addSyntheticTask,
1043
- removeSyntheticTask
1052
+ removeSyntheticTask,
1053
+ fieldRefs,
1054
+ fieldRefsByTypePath
1044
1055
  };
1045
1056
  return assistDocument ? {
1046
1057
  ...base,
@@ -2870,12 +2881,12 @@ function useCustomFieldActions(props) {
2870
2881
  path: props.path
2871
2882
  });
2872
2883
  return useMemo(() => {
2873
- const title = fieldActions?.title, customActions = configActions?.map((node) => createSafeNode({
2884
+ const title = fieldActions?.title, customActions = configActions?.filter(isDefined).map((node) => createSafeNode({
2874
2885
  node,
2875
2886
  pushToast,
2876
2887
  addSyntheticTask,
2877
2888
  removeSyntheticTask
2878
- })), onlyGroups = customActions?.length && customActions?.every((node) => node.type === "group");
2889
+ })).filter(isDefined), onlyGroups = customActions?.length && customActions?.every((node) => node.type === "group");
2879
2890
  return (customActions?.length ? onlyGroups ? customActions : [
2880
2891
  {
2881
2892
  type: "group",
@@ -2892,12 +2903,13 @@ function createSafeNode(args) {
2892
2903
  case "action":
2893
2904
  return createSafeAction({ ...args, action: node });
2894
2905
  case "group":
2895
- return {
2906
+ const children = node.children?.filter(isDefined).map((child) => createSafeNode({ ...args, node: child })).filter(isDefined);
2907
+ return children?.length ? {
2896
2908
  ...node,
2897
2909
  renderAsButton: !1,
2898
2910
  expanded: !0,
2899
- children: node.children?.map((child) => createSafeNode({ ...args, node: child }))
2900
- };
2911
+ children
2912
+ } : void 0;
2901
2913
  case "divider":
2902
2914
  default:
2903
2915
  return node;
@@ -2955,7 +2967,8 @@ const assistFieldActions = {
2955
2967
  documentOnChange,
2956
2968
  documentSchemaType,
2957
2969
  selectedPath,
2958
- assistableDocumentId
2970
+ assistableDocumentId,
2971
+ fieldRefsByTypePath
2959
2972
  } = useAssistDocumentContext(), { value: docValue, formState } = useDocumentPane(), docValueRef = useRef(docValue), formStateRef = useRef(formState);
2960
2973
  formStateRef.current = formState;
2961
2974
  const currentUser = useCurrentUser(), isHidden = !assistDocument, pathKey = usePathKey(props.path), typePath = useTypePath(docValue, pathKey), assistDocumentId2 = assistDocument?._id, { requestRunInstruction } = useRequestRunInstruction({
@@ -3043,14 +3056,22 @@ const assistFieldActions = {
3043
3056
  path
3044
3057
  };
3045
3058
  }
3046
- ), []), customActions = useCustomFieldActions({
3059
+ ), []), parentSchemaType = useMemo(() => {
3060
+ if (props.path.length) {
3061
+ if (props.path.length === 1)
3062
+ return documentSchemaType;
3063
+ } else return;
3064
+ const parentPath = props.path.slice(0, -1), typePath2 = getTypePath(docValueRef.current, pathToString(parentPath));
3065
+ return typePath2 ? fieldRefsByTypePath[typePath2]?.schemaType : void 0;
3066
+ }, [fieldRefsByTypePath, props.path, documentSchemaType]), customActions = useCustomFieldActions({
3047
3067
  actionType: props.path.length ? "field" : "document",
3048
3068
  documentIdForAction: assistableDocumentId,
3049
3069
  schemaType,
3050
3070
  documentSchemaType,
3051
3071
  path: props.path,
3052
3072
  getDocumentValue,
3053
- getConditionalPaths
3073
+ getConditionalPaths,
3074
+ parentSchemaType
3054
3075
  }), manageInstructionsItem = useMemo(
3055
3076
  () => ({
3056
3077
  type: "action",