@sanity/assist 4.1.0 → 4.3.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 +302 -0
- package/dist/index.d.mts +269 -1
- package/dist/index.d.ts +269 -1
- package/dist/index.esm.js +244 -103
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +239 -98
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +244 -103
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -8
- package/src/assistDocument/AssistDocumentContext.tsx +14 -1
- package/src/assistDocument/hooks/useAssistDocumentContextValue.tsx +30 -3
- package/src/assistLayout/RunInstructionProvider.tsx +75 -23
- package/src/components/ImageContext.tsx +4 -4
- package/src/fieldActions/assistFieldActions.tsx +42 -2
- package/src/fieldActions/customFieldActions.tsx +304 -0
- package/src/fieldActions/useUserInput.ts +107 -0
- package/src/helpers/typeUtils.ts +13 -3
- package/src/index.ts +17 -0
- package/src/plugin.tsx +6 -0
- package/src/presence/AssistDocumentPresence.tsx +3 -3
- package/src/schemas/typeDefExtensions.ts +12 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sanity/assist",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.3.0",
|
|
4
4
|
"description": "You create the instructions; Sanity AI Assist does the rest.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"sanity",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"dependencies": {
|
|
52
52
|
"@sanity/icons": "^3.5.2",
|
|
53
53
|
"@sanity/incompatible-plugin": "^1.0.4",
|
|
54
|
-
"@sanity/ui": "^2.
|
|
54
|
+
"@sanity/ui": "^2.15.18",
|
|
55
55
|
"date-fns": "^3.6.0",
|
|
56
56
|
"lodash": "^4.17.21",
|
|
57
57
|
"lodash-es": "^4.17.21",
|
|
@@ -63,9 +63,9 @@
|
|
|
63
63
|
"@commitlint/cli": "^19.2.1",
|
|
64
64
|
"@commitlint/config-conventional": "^19.1.0",
|
|
65
65
|
"@rollup/plugin-image": "^3.0.3",
|
|
66
|
-
"@sanity/pkg-utils": "^6.
|
|
66
|
+
"@sanity/pkg-utils": "^6.13.4",
|
|
67
67
|
"@sanity/plugin-kit": "^3.1.10",
|
|
68
|
-
"@sanity/schema": "^3.
|
|
68
|
+
"@sanity/schema": "^3.91.0",
|
|
69
69
|
"@sanity/semantic-release-preset": "^4.1.7",
|
|
70
70
|
"@types/lodash": "^4.17.0",
|
|
71
71
|
"@types/lodash-es": "^4.17.12",
|
|
@@ -83,11 +83,11 @@
|
|
|
83
83
|
"react": "^18.2.0",
|
|
84
84
|
"react-dom": "^18.2.0",
|
|
85
85
|
"rimraf": "^5.0.5",
|
|
86
|
-
"sanity": "^3.
|
|
86
|
+
"sanity": "^3.91.0",
|
|
87
87
|
"semantic-release": "^23.0.8",
|
|
88
88
|
"styled-components": "^6.1.16",
|
|
89
89
|
"typescript": "^5.7.2",
|
|
90
|
-
"vitest": "^1.4
|
|
90
|
+
"vitest": "^3.1.4"
|
|
91
91
|
},
|
|
92
92
|
"peerDependencies": {
|
|
93
93
|
"@sanity/mutator": "^3.36.4",
|
|
@@ -96,9 +96,10 @@
|
|
|
96
96
|
"styled-components": "^6.1"
|
|
97
97
|
},
|
|
98
98
|
"engines": {
|
|
99
|
-
"node": ">=
|
|
99
|
+
"node": ">=20"
|
|
100
100
|
},
|
|
101
101
|
"publishConfig": {
|
|
102
102
|
"access": "public"
|
|
103
|
-
}
|
|
103
|
+
},
|
|
104
|
+
"browserslist": "extends @sanity/browserslist-config"
|
|
104
105
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {createContext, useContext} from 'react'
|
|
2
2
|
import {DocumentInspector, ObjectSchemaType, PatchEvent} from 'sanity'
|
|
3
3
|
|
|
4
|
-
import {StudioAssistDocument} from '../types'
|
|
4
|
+
import {InstructionTask, StudioAssistDocument} from '../types'
|
|
5
5
|
|
|
6
6
|
export type AssistDocumentContextValue = (
|
|
7
7
|
| {assistDocument: StudioAssistDocument; loading: false}
|
|
@@ -19,6 +19,19 @@ export type AssistDocumentContextValue = (
|
|
|
19
19
|
inspector: DocumentInspector | null
|
|
20
20
|
selectedPath?: string
|
|
21
21
|
documentOnChange: (event: PatchEvent) => void
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Synthetic task is used to display AI presence at the document level for the user who started the action.
|
|
25
|
+
* These are not persisted, so other users will not see them.
|
|
26
|
+
* It is mostly a helper to give _some_ visual feedback to the user while a custom action is running.
|
|
27
|
+
* This also means that reloading the page will remove the icon.
|
|
28
|
+
*
|
|
29
|
+
* Agent Actions add their own "real" tasks, so if a custom action calls an Agent action, _those_ tasks
|
|
30
|
+
* are visible across sessions.
|
|
31
|
+
*/
|
|
32
|
+
syntheticTasks?: InstructionTask[]
|
|
33
|
+
addSyntheticTask: (syntheticTask: InstructionTask) => void
|
|
34
|
+
removeSyntheticTask: (syntheticTask: InstructionTask) => void
|
|
22
35
|
}
|
|
23
36
|
|
|
24
37
|
export const AssistDocumentContext = createContext<AssistDocumentContextValue | undefined>(
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
import {useMemo} from 'react'
|
|
1
|
+
import {useCallback, useEffect, useMemo, useState} from 'react'
|
|
2
2
|
import {getDraftId, getVersionId, type ObjectSchemaType, useSchema} from 'sanity'
|
|
3
3
|
import {useDocumentPane} from 'sanity/structure'
|
|
4
4
|
|
|
5
5
|
import {useAiPaneRouter} from '../../assistInspector/helpers'
|
|
6
|
-
import {fieldPathParam} from '../../types'
|
|
6
|
+
import {fieldPathParam, InstructionTask} from '../../types'
|
|
7
7
|
import type {AssistDocumentContextValue} from '../AssistDocumentContext'
|
|
8
8
|
import {isDocAssistable} from '../RequestRunInstructionProvider'
|
|
9
9
|
import {useStudioAssistDocument} from './useStudioAssistDocument'
|
|
@@ -51,7 +51,8 @@ export function useAssistDocumentContextValue(documentId: string, documentType:
|
|
|
51
51
|
documentId: assistableDocumentId,
|
|
52
52
|
schemaType: documentSchemaType,
|
|
53
53
|
})
|
|
54
|
-
|
|
54
|
+
const {syntheticTasks, addSyntheticTask, removeSyntheticTask} =
|
|
55
|
+
useSyntheticTasks(assistableDocumentId)
|
|
55
56
|
const value: AssistDocumentContextValue = useMemo(() => {
|
|
56
57
|
const base = {
|
|
57
58
|
assistableDocumentId,
|
|
@@ -63,6 +64,9 @@ export function useAssistDocumentContextValue(documentId: string, documentType:
|
|
|
63
64
|
inspector,
|
|
64
65
|
documentOnChange,
|
|
65
66
|
selectedPath,
|
|
67
|
+
syntheticTasks,
|
|
68
|
+
addSyntheticTask,
|
|
69
|
+
removeSyntheticTask,
|
|
66
70
|
}
|
|
67
71
|
if (!assistDocument) {
|
|
68
72
|
return {...base, loading: true, assistDocument: undefined}
|
|
@@ -83,7 +87,30 @@ export function useAssistDocumentContextValue(documentId: string, documentType:
|
|
|
83
87
|
inspector,
|
|
84
88
|
documentOnChange,
|
|
85
89
|
selectedPath,
|
|
90
|
+
syntheticTasks,
|
|
91
|
+
addSyntheticTask,
|
|
92
|
+
removeSyntheticTask,
|
|
86
93
|
])
|
|
87
94
|
|
|
88
95
|
return value
|
|
89
96
|
}
|
|
97
|
+
|
|
98
|
+
function useSyntheticTasks(assistableDocumentId: string) {
|
|
99
|
+
const [syntheticTasks, setSyntheticTasks] = useState<InstructionTask[]>(() => [])
|
|
100
|
+
const addSyntheticTask = useCallback((task: InstructionTask) => {
|
|
101
|
+
setSyntheticTasks((current) => [...current, task])
|
|
102
|
+
}, [])
|
|
103
|
+
const removeSyntheticTask = useCallback((task: InstructionTask) => {
|
|
104
|
+
setSyntheticTasks((current) => current.filter((t) => task._key !== t._key))
|
|
105
|
+
}, [])
|
|
106
|
+
|
|
107
|
+
useEffect(() => {
|
|
108
|
+
setSyntheticTasks([])
|
|
109
|
+
}, [assistableDocumentId])
|
|
110
|
+
|
|
111
|
+
return {
|
|
112
|
+
syntheticTasks,
|
|
113
|
+
addSyntheticTask,
|
|
114
|
+
removeSyntheticTask,
|
|
115
|
+
}
|
|
116
|
+
}
|
|
@@ -1,5 +1,13 @@
|
|
|
1
1
|
import {PlayIcon} from '@sanity/icons'
|
|
2
2
|
import {Button, Dialog, Flex, Stack, Text, TextArea, Tooltip} from '@sanity/ui'
|
|
3
|
+
import {FormFieldHeaderText} from 'sanity'
|
|
4
|
+
|
|
5
|
+
import {getInstructionTitle} from '../helpers/misc'
|
|
6
|
+
import {type UserInputBlock, userInputTypeName} from '../types'
|
|
7
|
+
import {useApiClient, useRunInstructionApi} from '../useApiClient'
|
|
8
|
+
import {useAiAssistanceConfig} from './AiAssistanceConfigContext'
|
|
9
|
+
import type {RunInstructionArgs} from './AssistLayout'
|
|
10
|
+
import {CustomInputResult, GetUserInput} from '../fieldActions/useUserInput'
|
|
3
11
|
import {
|
|
4
12
|
createContext,
|
|
5
13
|
type Dispatch,
|
|
@@ -14,24 +22,19 @@ import {
|
|
|
14
22
|
useRef,
|
|
15
23
|
useState,
|
|
16
24
|
} from 'react'
|
|
17
|
-
import {FormFieldHeaderText} from 'sanity'
|
|
18
|
-
|
|
19
|
-
import {getInstructionTitle} from '../helpers/misc'
|
|
20
|
-
import {type UserInputBlock, userInputTypeName} from '../types'
|
|
21
|
-
import {useApiClient, useRunInstructionApi} from '../useApiClient'
|
|
22
|
-
import {useAiAssistanceConfig} from './AiAssistanceConfigContext'
|
|
23
|
-
import type {RunInstructionArgs} from './AssistLayout'
|
|
24
25
|
|
|
25
26
|
type BlockInputs = Record<string, string>
|
|
26
27
|
const NO_INPUT: BlockInputs = {}
|
|
27
28
|
|
|
28
29
|
export interface RunInstructionContextValue {
|
|
29
30
|
runInstruction: (req: RunInstructionArgs) => void
|
|
31
|
+
getUserInput: GetUserInput
|
|
30
32
|
instructionLoading: boolean
|
|
31
33
|
}
|
|
32
34
|
|
|
33
35
|
export const RunInstructionContext = createContext<RunInstructionContextValue>({
|
|
34
36
|
runInstruction: () => {},
|
|
37
|
+
getUserInput: async () => undefined,
|
|
35
38
|
instructionLoading: false,
|
|
36
39
|
})
|
|
37
40
|
|
|
@@ -53,9 +56,34 @@ export function RunInstructionProvider(props: PropsWithChildren<{}>) {
|
|
|
53
56
|
|
|
54
57
|
const [inputs, setInputs] = useState(NO_INPUT)
|
|
55
58
|
const [runRequest, setRunRequest] = useState<
|
|
56
|
-
(RunInstructionArgs & {userInputBlocks: UserInputBlock[]})
|
|
59
|
+
| (RunInstructionArgs & {userInputBlocks: UserInputBlock[]})
|
|
60
|
+
| {dialogTitle: string; userInputBlocks: UserInputBlock[]}
|
|
61
|
+
| undefined
|
|
57
62
|
>()
|
|
58
63
|
|
|
64
|
+
const [resolveUserInput, setResolveUserInput] =
|
|
65
|
+
useState<
|
|
66
|
+
(
|
|
67
|
+
value: CustomInputResult[] | PromiseLike<CustomInputResult[] | undefined> | undefined,
|
|
68
|
+
) => void
|
|
69
|
+
>()
|
|
70
|
+
|
|
71
|
+
const getUserInput: GetUserInput = useCallback(async ({title, inputs}) => {
|
|
72
|
+
const userInputBlocks: UserInputBlock[] = inputs.map((input, i) => ({
|
|
73
|
+
_type: userInputTypeName,
|
|
74
|
+
_key: input.id ?? `${i}`,
|
|
75
|
+
message: input.title,
|
|
76
|
+
description: input.description,
|
|
77
|
+
}))
|
|
78
|
+
if (!userInputBlocks.length) {
|
|
79
|
+
return undefined
|
|
80
|
+
}
|
|
81
|
+
setRunRequest({dialogTitle: title, userInputBlocks})
|
|
82
|
+
return new Promise<CustomInputResult[] | undefined>((resolve) => {
|
|
83
|
+
setResolveUserInput(() => resolve)
|
|
84
|
+
})
|
|
85
|
+
}, [])
|
|
86
|
+
|
|
59
87
|
const runInstruction = useCallback(
|
|
60
88
|
(req: RunInstructionArgs) => {
|
|
61
89
|
if (loading) {
|
|
@@ -89,23 +117,43 @@ export function RunInstructionProvider(props: PropsWithChildren<{}>) {
|
|
|
89
117
|
const close = useCallback(() => {
|
|
90
118
|
setRunRequest(undefined)
|
|
91
119
|
setInputs(NO_INPUT)
|
|
92
|
-
|
|
120
|
+
if (resolveUserInput) {
|
|
121
|
+
resolveUserInput(undefined)
|
|
122
|
+
}
|
|
123
|
+
setResolveUserInput(undefined)
|
|
124
|
+
}, [resolveUserInput])
|
|
93
125
|
|
|
94
126
|
const runWithInput = useCallback(() => {
|
|
95
127
|
if (runRequest) {
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
128
|
+
if ('instruction' in runRequest) {
|
|
129
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
130
|
+
const {instruction, userTexts, ...request} = runRequest
|
|
131
|
+
runInstructionRequest({
|
|
132
|
+
...request,
|
|
133
|
+
instructionKey: instruction._key,
|
|
134
|
+
userTexts: Object.entries(inputs).map(([key, value]) => ({
|
|
135
|
+
blockKey: key,
|
|
136
|
+
userInput: value,
|
|
137
|
+
})),
|
|
138
|
+
})
|
|
139
|
+
} else {
|
|
140
|
+
const userInputs = Object.values(inputs).map((input, i) => {
|
|
141
|
+
const userInputBlock = runRequest.userInputBlocks[i]
|
|
142
|
+
return {
|
|
143
|
+
input: {
|
|
144
|
+
id: userInputBlock._key,
|
|
145
|
+
title: userInputBlock.message ?? '',
|
|
146
|
+
description: userInputBlock.description,
|
|
147
|
+
},
|
|
148
|
+
result: input,
|
|
149
|
+
}
|
|
150
|
+
})
|
|
151
|
+
resolveUserInput?.(userInputs)
|
|
152
|
+
setResolveUserInput(undefined)
|
|
153
|
+
}
|
|
106
154
|
}
|
|
107
155
|
close()
|
|
108
|
-
}, [close, runInstructionRequest, runRequest, inputs])
|
|
156
|
+
}, [close, runInstructionRequest, runRequest, inputs, resolveUserInput])
|
|
109
157
|
|
|
110
158
|
const open = !!runRequest
|
|
111
159
|
|
|
@@ -128,7 +176,7 @@ export function RunInstructionProvider(props: PropsWithChildren<{}>) {
|
|
|
128
176
|
)
|
|
129
177
|
|
|
130
178
|
const contextValue: RunInstructionContextValue = useMemo(
|
|
131
|
-
() => ({runInstruction, instructionLoading: loading}),
|
|
179
|
+
() => ({runInstruction, getUserInput, instructionLoading: loading}),
|
|
132
180
|
[runInstruction, loading],
|
|
133
181
|
)
|
|
134
182
|
|
|
@@ -140,7 +188,11 @@ export function RunInstructionProvider(props: PropsWithChildren<{}>) {
|
|
|
140
188
|
open={open}
|
|
141
189
|
onClose={close}
|
|
142
190
|
width={1}
|
|
143
|
-
header={
|
|
191
|
+
header={
|
|
192
|
+
'dialogTitle' in runRequest
|
|
193
|
+
? runRequest.dialogTitle
|
|
194
|
+
: getInstructionTitle(runRequest?.instruction)
|
|
195
|
+
}
|
|
144
196
|
footer={
|
|
145
197
|
<Flex justify="space-between" padding={2} flex={1}>
|
|
146
198
|
{runDisabled ? (
|
|
@@ -178,7 +230,7 @@ export function RunInstructionProvider(props: PropsWithChildren<{}>) {
|
|
|
178
230
|
)
|
|
179
231
|
}
|
|
180
232
|
|
|
181
|
-
function UserInput(props: {
|
|
233
|
+
export function UserInput(props: {
|
|
182
234
|
block: UserInputBlock
|
|
183
235
|
inputs: BlockInputs
|
|
184
236
|
setInputs: Dispatch<SetStateAction<BlockInputs>>
|
|
@@ -40,7 +40,7 @@ export function ImageContextProvider(props: InputProps) {
|
|
|
40
40
|
if (
|
|
41
41
|
assetRef &&
|
|
42
42
|
assistableDocumentId &&
|
|
43
|
-
descriptionField &&
|
|
43
|
+
descriptionField?.updateOnImageChange &&
|
|
44
44
|
assetRef !== assetRefState &&
|
|
45
45
|
!isSyncing &&
|
|
46
46
|
!isShowingOlderRevision &&
|
|
@@ -49,7 +49,7 @@ export function ImageContextProvider(props: InputProps) {
|
|
|
49
49
|
setAssetRefState(assetRef)
|
|
50
50
|
if (canUseAssist(status)) {
|
|
51
51
|
generateCaption({
|
|
52
|
-
path: pathToString([...path, descriptionField]),
|
|
52
|
+
path: pathToString([...path, descriptionField.path]),
|
|
53
53
|
documentId: assistableDocumentId,
|
|
54
54
|
})
|
|
55
55
|
}
|
|
@@ -71,8 +71,8 @@ export function ImageContextProvider(props: InputProps) {
|
|
|
71
71
|
const descriptionField = getDescriptionFieldOption(schemaType)
|
|
72
72
|
const imageInstructionField = getImageInstructionFieldOption(schemaType)
|
|
73
73
|
return {
|
|
74
|
-
imageDescriptionPath: descriptionField
|
|
75
|
-
? pathToString([...path, descriptionField])
|
|
74
|
+
imageDescriptionPath: descriptionField?.path
|
|
75
|
+
? pathToString([...path, descriptionField.path])
|
|
76
76
|
: undefined,
|
|
77
77
|
imageInstructionPath: imageInstructionField
|
|
78
78
|
? pathToString([...path, imageInstructionField])
|
|
@@ -4,6 +4,7 @@ import {
|
|
|
4
4
|
type DocumentFieldAction,
|
|
5
5
|
type DocumentFieldActionGroup,
|
|
6
6
|
type DocumentFieldActionItem,
|
|
7
|
+
stringToPath,
|
|
7
8
|
typed,
|
|
8
9
|
useCurrentUser,
|
|
9
10
|
} from 'sanity'
|
|
@@ -24,6 +25,8 @@ import {documentRootKey, fieldPathParam, instructionParam, type StudioInstructio
|
|
|
24
25
|
import {generateCaptionsActions} from './generateCaptionActions'
|
|
25
26
|
import {generateImagActions} from './generateImageActions'
|
|
26
27
|
import {PrivateIcon} from './PrivateIcon'
|
|
28
|
+
import {AgentActionConditionalPath, useCustomFieldActions} from './customFieldActions'
|
|
29
|
+
import {AgentActionPath} from '@sanity/client/stega'
|
|
27
30
|
|
|
28
31
|
function node(node: DocumentFieldActionItem | DocumentFieldActionGroup) {
|
|
29
32
|
return node
|
|
@@ -48,6 +51,7 @@ export const assistFieldActions: DocumentFieldAction = {
|
|
|
48
51
|
} = useAssistDocumentContext()
|
|
49
52
|
|
|
50
53
|
const {value: docValue, formState} = useDocumentPane()
|
|
54
|
+
const docValueRef = useRef(docValue)
|
|
51
55
|
const formStateRef = useRef(formState)
|
|
52
56
|
formStateRef.current = formState
|
|
53
57
|
|
|
@@ -180,7 +184,35 @@ export const assistFieldActions: DocumentFieldAction = {
|
|
|
180
184
|
imageGenAction,
|
|
181
185
|
])
|
|
182
186
|
|
|
183
|
-
const
|
|
187
|
+
const getDocumentValue = useCallback(() => {
|
|
188
|
+
return docValueRef.current
|
|
189
|
+
}, [])
|
|
190
|
+
|
|
191
|
+
const getConditionalPaths: () => AgentActionConditionalPath[] = useCallback(() => {
|
|
192
|
+
return (formStateRef.current ? getConditionalMembers(formStateRef.current) : []).flatMap(
|
|
193
|
+
(cm) => {
|
|
194
|
+
const path = stringToPath(cm.path)
|
|
195
|
+
if (path.some((s) => typeof s === 'number')) {
|
|
196
|
+
//agent actions does not support indexed paths
|
|
197
|
+
return []
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
...cm,
|
|
201
|
+
path: path as AgentActionPath,
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
)
|
|
205
|
+
}, [])
|
|
206
|
+
|
|
207
|
+
const customActions = useCustomFieldActions({
|
|
208
|
+
actionType: props.path.length ? 'field' : 'document',
|
|
209
|
+
documentIdForAction: assistableDocumentId,
|
|
210
|
+
schemaType,
|
|
211
|
+
documentSchemaType,
|
|
212
|
+
path: props.path,
|
|
213
|
+
getDocumentValue,
|
|
214
|
+
getConditionalPaths,
|
|
215
|
+
})
|
|
184
216
|
|
|
185
217
|
const manageInstructionsItem = useMemo(
|
|
186
218
|
() =>
|
|
@@ -203,6 +235,7 @@ export const assistFieldActions: DocumentFieldAction = {
|
|
|
203
235
|
children: [
|
|
204
236
|
runInstructionsGroup,
|
|
205
237
|
translateAction,
|
|
238
|
+
...customActions,
|
|
206
239
|
assistSupported && manageInstructionsItem,
|
|
207
240
|
]
|
|
208
241
|
.filter((c): c is DocumentFieldActionItem | DocumentFieldActionGroup => !!c)
|
|
@@ -219,6 +252,7 @@ export const assistFieldActions: DocumentFieldAction = {
|
|
|
219
252
|
imageCaptionAction,
|
|
220
253
|
translateAction,
|
|
221
254
|
imageGenAction,
|
|
255
|
+
customActions,
|
|
222
256
|
],
|
|
223
257
|
)
|
|
224
258
|
|
|
@@ -237,7 +271,13 @@ export const assistFieldActions: DocumentFieldAction = {
|
|
|
237
271
|
)
|
|
238
272
|
|
|
239
273
|
// If there are no instructions, we don't want to render the group
|
|
240
|
-
if (
|
|
274
|
+
if (
|
|
275
|
+
!instructions?.length &&
|
|
276
|
+
!imageCaptionAction &&
|
|
277
|
+
!translateAction &&
|
|
278
|
+
!imageGenAction &&
|
|
279
|
+
!customActions.length
|
|
280
|
+
) {
|
|
241
281
|
return emptyAction
|
|
242
282
|
}
|
|
243
283
|
|