@sanity/assist 5.0.4 → 6.0.1
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/LICENSE +1 -1
- package/README.md +28 -254
- package/dist/index.d.ts +322 -410
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3205 -2670
- package/dist/index.js.map +1 -1
- package/package.json +41 -81
- package/dist/index.cjs +0 -4239
- package/dist/index.cjs.map +0 -1
- package/dist/index.d.cts +0 -791
- package/sanity.json +0 -8
- package/src/_lib/connector/ConnectFromRegion.tsx +0 -25
- package/src/_lib/connector/ConnectToRegion.tsx +0 -23
- package/src/_lib/connector/ConnectorRegion.tsx +0 -24
- package/src/_lib/connector/ConnectorsProvider.tsx +0 -20
- package/src/_lib/connector/ConnectorsStore.ts +0 -122
- package/src/_lib/connector/ConnectorsStoreContext.ts +0 -5
- package/src/_lib/connector/helpers.ts +0 -5
- package/src/_lib/connector/index.ts +0 -9
- package/src/_lib/connector/mapConnectorToLine.ts +0 -83
- package/src/_lib/connector/types.ts +0 -56
- package/src/_lib/connector/useConnectorsStore.ts +0 -14
- package/src/_lib/connector/useRegionRects.ts +0 -142
- package/src/_lib/fixedListenQuery.ts +0 -101
- package/src/_lib/form/DocumentForm.tsx +0 -201
- package/src/_lib/form/constants.ts +0 -1
- package/src/_lib/form/helpers.ts +0 -32
- package/src/_lib/form/index.ts +0 -1
- package/src/_lib/randomKey.ts +0 -29
- package/src/_lib/useListeningQuery.ts +0 -62
- package/src/_lib/usePrevious.ts +0 -9
- package/src/assistConnectors/AssistConnectorsOverlay.tsx +0 -133
- package/src/assistConnectors/ConnectorPath.tsx +0 -63
- package/src/assistConnectors/draw/arrowPath.ts +0 -9
- package/src/assistConnectors/draw/connectorPath.ts +0 -142
- package/src/assistConnectors/index.ts +0 -1
- package/src/assistDocument/AssistDocumentContext.tsx +0 -51
- package/src/assistDocument/AssistDocumentContextProvider.tsx +0 -17
- package/src/assistDocument/AssistDocumentInput.tsx +0 -61
- package/src/assistDocument/AssistDocumentLayout.tsx +0 -12
- package/src/assistDocument/RequestRunInstructionProvider.tsx +0 -61
- package/src/assistDocument/components/AssistDocumentForm.tsx +0 -287
- package/src/assistDocument/components/AssistTypeContext.tsx +0 -7
- package/src/assistDocument/components/FieldRefPreview.tsx +0 -26
- package/src/assistDocument/components/InstructionsArrayField.tsx +0 -8
- package/src/assistDocument/components/InstructionsArrayInput.tsx +0 -27
- package/src/assistDocument/components/SelectedFieldContext.tsx +0 -10
- package/src/assistDocument/components/generic/HiddenFieldTitle.tsx +0 -5
- package/src/assistDocument/components/helpers.ts +0 -21
- package/src/assistDocument/components/instruction/BackToInstructionsLink.tsx +0 -32
- package/src/assistDocument/components/instruction/FieldRefInput.tsx +0 -54
- package/src/assistDocument/components/instruction/InstructionInput.tsx +0 -89
- package/src/assistDocument/components/instruction/InstructionOutputField.tsx +0 -46
- package/src/assistDocument/components/instruction/InstructionOutputInput.tsx +0 -206
- package/src/assistDocument/components/instruction/PromptInput.tsx +0 -59
- package/src/assistDocument/components/instruction/appearance/IconInput.tsx +0 -46
- package/src/assistDocument/components/instruction/appearance/InstructionVisibility.tsx +0 -37
- package/src/assistDocument/hooks/useAssistDocumentContextValue.tsx +0 -127
- package/src/assistDocument/hooks/useDocumentState.ts +0 -6
- package/src/assistDocument/hooks/useInstructionToaster.tsx +0 -75
- package/src/assistDocument/hooks/useStudioAssistDocument.ts +0 -99
- package/src/assistDocument/index.ts +0 -1
- package/src/assistFormComponents/AssistField.tsx +0 -63
- package/src/assistFormComponents/AssistFormBlock.tsx +0 -31
- package/src/assistFormComponents/AssistInlineFormBlock.tsx +0 -13
- package/src/assistFormComponents/AssistItem.tsx +0 -21
- package/src/assistFormComponents/validation/listItem.tsx +0 -63
- package/src/assistFormComponents/validation/validationList.tsx +0 -90
- package/src/assistInspector/AssistInspector.tsx +0 -419
- package/src/assistInspector/FieldAutocomplete.tsx +0 -146
- package/src/assistInspector/InstructionTaskHistoryButton.tsx +0 -262
- package/src/assistInspector/constants.ts +0 -1
- package/src/assistInspector/helpers.ts +0 -211
- package/src/assistInspector/index.ts +0 -27
- package/src/assistLayout/AiAssistanceConfigContext.tsx +0 -32
- package/src/assistLayout/AiAssistanceConfigProvider.tsx +0 -98
- package/src/assistLayout/AssistLayout.tsx +0 -39
- package/src/assistLayout/RunInstructionProvider.tsx +0 -278
- package/src/assistLayout/fieldRefCache.tsx +0 -34
- package/src/assistTypes.ts +0 -83
- package/src/components/AssistFeatureBadge.tsx +0 -9
- package/src/components/FadeInContent.tsx +0 -40
- package/src/components/HideReferenceChangedBannerInput.tsx +0 -25
- package/src/components/ImageContext.tsx +0 -85
- package/src/components/SafeValueInput.tsx +0 -74
- package/src/components/TimeAgo.tsx +0 -18
- package/src/constants.ts +0 -20
- package/src/fieldActions/PrivateIcon.tsx +0 -20
- package/src/fieldActions/assistFieldActions.tsx +0 -320
- package/src/fieldActions/customFieldActions.tsx +0 -333
- package/src/fieldActions/generateCaptionActions.tsx +0 -77
- package/src/fieldActions/generateImageActions.tsx +0 -58
- package/src/fieldActions/useUserInput.ts +0 -107
- package/src/globals.d.ts +0 -4
- package/src/helpers/assistSupported.ts +0 -49
- package/src/helpers/conditionalMembers.test.ts +0 -319
- package/src/helpers/conditionalMembers.ts +0 -134
- package/src/helpers/ids.test.ts +0 -28
- package/src/helpers/ids.ts +0 -23
- package/src/helpers/misc.ts +0 -25
- package/src/helpers/styleguide.ts +0 -24
- package/src/helpers/typeUtils.ts +0 -60
- package/src/helpers/useAssistSupported.ts +0 -8
- package/src/index.ts +0 -26
- package/src/onboarding/FirstAssistedPathProvider.tsx +0 -30
- package/src/onboarding/InspectorOnboarding.tsx +0 -47
- package/src/onboarding/onboardingStore.ts +0 -32
- package/src/plugin.tsx +0 -162
- package/src/presence/AiFieldPresence.tsx +0 -28
- package/src/presence/AssistAvatar.tsx +0 -96
- package/src/presence/AssistDocumentPresence.tsx +0 -50
- package/src/presence/useAssistPresence.ts +0 -64
- package/src/schemas/assistDocumentSchema.tsx +0 -497
- package/src/schemas/contextDocumentSchema.tsx +0 -57
- package/src/schemas/index.ts +0 -69
- package/src/schemas/serialize/SchemTypeTool.tsx +0 -103
- package/src/schemas/serialize/schemaUtils.ts +0 -38
- package/src/schemas/serialize/serializeSchema.test.ts +0 -819
- package/src/schemas/serialize/serializeSchema.ts +0 -224
- package/src/schemas/serializedSchemaTypeSchema.ts +0 -60
- package/src/schemas/typeDefExtensions.ts +0 -127
- package/src/translate/FieldTranslationProvider.tsx +0 -382
- package/src/translate/getLanguageParams.ts +0 -26
- package/src/translate/languageStore.ts +0 -18
- package/src/translate/paths.test.ts +0 -181
- package/src/translate/paths.ts +0 -183
- package/src/translate/translateActions.tsx +0 -205
- package/src/translate/types.ts +0 -197
- package/src/types.ts +0 -220
- package/src/useApiClient.ts +0 -338
- package/v2-incompatible.js +0 -11
|
@@ -1,278 +0,0 @@
|
|
|
1
|
-
import {PlayIcon} from '@sanity/icons'
|
|
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'
|
|
11
|
-
import {
|
|
12
|
-
createContext,
|
|
13
|
-
type Dispatch,
|
|
14
|
-
type FormEvent,
|
|
15
|
-
type PropsWithChildren,
|
|
16
|
-
type SetStateAction,
|
|
17
|
-
useCallback,
|
|
18
|
-
useContext,
|
|
19
|
-
useEffect,
|
|
20
|
-
useId,
|
|
21
|
-
useMemo,
|
|
22
|
-
useRef,
|
|
23
|
-
useState,
|
|
24
|
-
} from 'react'
|
|
25
|
-
|
|
26
|
-
type BlockInputs = Record<string, string>
|
|
27
|
-
const NO_INPUT: BlockInputs = {}
|
|
28
|
-
|
|
29
|
-
export interface RunInstructionContextValue {
|
|
30
|
-
runInstruction: (req: RunInstructionArgs) => void
|
|
31
|
-
getUserInput: GetUserInput
|
|
32
|
-
instructionLoading: boolean
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export const RunInstructionContext = createContext<RunInstructionContextValue>({
|
|
36
|
-
runInstruction: () => {},
|
|
37
|
-
getUserInput: async () => undefined,
|
|
38
|
-
instructionLoading: false,
|
|
39
|
-
})
|
|
40
|
-
|
|
41
|
-
export function useRunInstruction() {
|
|
42
|
-
return useContext(RunInstructionContext)
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function isUserInputBlock(block: {_type: string}): block is UserInputBlock {
|
|
46
|
-
return block._type === userInputTypeName
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
// eslint-disable-next-line @typescript-eslint/ban-types
|
|
50
|
-
export function RunInstructionProvider(props: PropsWithChildren<{}>) {
|
|
51
|
-
const {config} = useAiAssistanceConfig()
|
|
52
|
-
const apiClient = useApiClient(config?.__customApiClient)
|
|
53
|
-
const {runInstruction: runInstructionRequest, loading} = useRunInstructionApi(apiClient)
|
|
54
|
-
|
|
55
|
-
const id = useId()
|
|
56
|
-
|
|
57
|
-
const [inputs, setInputs] = useState(NO_INPUT)
|
|
58
|
-
const [runRequest, setRunRequest] = useState<
|
|
59
|
-
| (RunInstructionArgs & {userInputBlocks: UserInputBlock[]})
|
|
60
|
-
| {dialogTitle: string; userInputBlocks: UserInputBlock[]}
|
|
61
|
-
| undefined
|
|
62
|
-
>()
|
|
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
|
-
|
|
79
|
-
if (!userInputBlocks.length) {
|
|
80
|
-
return undefined
|
|
81
|
-
}
|
|
82
|
-
setRunRequest({dialogTitle: title, userInputBlocks})
|
|
83
|
-
return new Promise<CustomInputResult[] | undefined>((resolve) => {
|
|
84
|
-
setResolveUserInput(() => resolve)
|
|
85
|
-
})
|
|
86
|
-
}, [])
|
|
87
|
-
|
|
88
|
-
const runInstruction = useCallback(
|
|
89
|
-
(req: RunInstructionArgs) => {
|
|
90
|
-
if (loading) {
|
|
91
|
-
return
|
|
92
|
-
}
|
|
93
|
-
const {instruction, ...request} = req
|
|
94
|
-
const instructionKey = instruction._key
|
|
95
|
-
const userInputBlocks = instruction?.prompt
|
|
96
|
-
?.flatMap((block) =>
|
|
97
|
-
block._type === 'block' ? block.children.filter(isUserInputBlock) : [block],
|
|
98
|
-
)
|
|
99
|
-
.filter(isUserInputBlock)
|
|
100
|
-
|
|
101
|
-
if (!userInputBlocks?.length) {
|
|
102
|
-
runInstructionRequest({
|
|
103
|
-
...request,
|
|
104
|
-
instructionKey,
|
|
105
|
-
userTexts: undefined,
|
|
106
|
-
})
|
|
107
|
-
return
|
|
108
|
-
}
|
|
109
|
-
|
|
110
|
-
setRunRequest({
|
|
111
|
-
...req,
|
|
112
|
-
userInputBlocks,
|
|
113
|
-
})
|
|
114
|
-
},
|
|
115
|
-
[runInstructionRequest, loading],
|
|
116
|
-
)
|
|
117
|
-
|
|
118
|
-
const close = useCallback(() => {
|
|
119
|
-
setRunRequest(undefined)
|
|
120
|
-
setInputs(NO_INPUT)
|
|
121
|
-
if (resolveUserInput) {
|
|
122
|
-
resolveUserInput(undefined)
|
|
123
|
-
}
|
|
124
|
-
setResolveUserInput(undefined)
|
|
125
|
-
}, [resolveUserInput])
|
|
126
|
-
|
|
127
|
-
const runWithInput = useCallback(() => {
|
|
128
|
-
if (runRequest) {
|
|
129
|
-
if ('instruction' in runRequest) {
|
|
130
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
131
|
-
const {instruction, userTexts, ...request} = runRequest
|
|
132
|
-
runInstructionRequest({
|
|
133
|
-
...request,
|
|
134
|
-
instructionKey: instruction._key,
|
|
135
|
-
userTexts: Object.entries(inputs).map(([key, value]) => ({
|
|
136
|
-
blockKey: key,
|
|
137
|
-
userInput: value,
|
|
138
|
-
})),
|
|
139
|
-
})
|
|
140
|
-
} else {
|
|
141
|
-
const userInputs = Object.values(inputs).map((input, i) => {
|
|
142
|
-
const userInputBlock = runRequest.userInputBlocks[i]
|
|
143
|
-
return {
|
|
144
|
-
input: {
|
|
145
|
-
id: userInputBlock._key,
|
|
146
|
-
title: userInputBlock.message ?? '',
|
|
147
|
-
description: userInputBlock.description,
|
|
148
|
-
},
|
|
149
|
-
result: input,
|
|
150
|
-
}
|
|
151
|
-
})
|
|
152
|
-
resolveUserInput?.(userInputs)
|
|
153
|
-
setResolveUserInput(undefined)
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
close()
|
|
157
|
-
}, [close, runInstructionRequest, runRequest, inputs, resolveUserInput])
|
|
158
|
-
|
|
159
|
-
const open = !!runRequest
|
|
160
|
-
|
|
161
|
-
const runDisabled = useMemo(
|
|
162
|
-
() =>
|
|
163
|
-
(runRequest?.userInputBlocks?.length ?? 0) >
|
|
164
|
-
Object.entries(inputs).filter(([, value]) => !!value).length,
|
|
165
|
-
[runRequest?.userInputBlocks, inputs],
|
|
166
|
-
)
|
|
167
|
-
|
|
168
|
-
const runButton = (
|
|
169
|
-
<Button
|
|
170
|
-
text="Run instruction"
|
|
171
|
-
onClick={runWithInput}
|
|
172
|
-
tone="primary"
|
|
173
|
-
icon={PlayIcon}
|
|
174
|
-
style={{width: '100%'}}
|
|
175
|
-
disabled={runDisabled}
|
|
176
|
-
/>
|
|
177
|
-
)
|
|
178
|
-
|
|
179
|
-
const contextValue: RunInstructionContextValue = useMemo(
|
|
180
|
-
() => ({runInstruction, getUserInput, instructionLoading: loading}),
|
|
181
|
-
[runInstruction, loading],
|
|
182
|
-
)
|
|
183
|
-
|
|
184
|
-
return (
|
|
185
|
-
<RunInstructionContext.Provider value={contextValue}>
|
|
186
|
-
{open ? (
|
|
187
|
-
<Dialog
|
|
188
|
-
id={id}
|
|
189
|
-
open={open}
|
|
190
|
-
onClose={close}
|
|
191
|
-
width={1}
|
|
192
|
-
header={
|
|
193
|
-
'dialogTitle' in runRequest
|
|
194
|
-
? runRequest.dialogTitle
|
|
195
|
-
: getInstructionTitle(runRequest?.instruction)
|
|
196
|
-
}
|
|
197
|
-
footer={
|
|
198
|
-
<Flex justify="space-between" padding={2} flex={1}>
|
|
199
|
-
{runDisabled ? (
|
|
200
|
-
<Tooltip
|
|
201
|
-
content={
|
|
202
|
-
<Flex padding={2}>
|
|
203
|
-
<Text>Unable to run instruction. All fields must have a value.</Text>
|
|
204
|
-
</Flex>
|
|
205
|
-
}
|
|
206
|
-
placement="top"
|
|
207
|
-
>
|
|
208
|
-
<Flex flex={1}>{runButton}</Flex>
|
|
209
|
-
</Tooltip>
|
|
210
|
-
) : (
|
|
211
|
-
runButton
|
|
212
|
-
)}
|
|
213
|
-
</Flex>
|
|
214
|
-
}
|
|
215
|
-
>
|
|
216
|
-
<Stack padding={4} space={2}>
|
|
217
|
-
{runRequest?.userInputBlocks?.map((block, i) => (
|
|
218
|
-
<UserInput
|
|
219
|
-
key={block._key}
|
|
220
|
-
block={block}
|
|
221
|
-
autoFocus={i === 0}
|
|
222
|
-
inputs={inputs}
|
|
223
|
-
setInputs={setInputs}
|
|
224
|
-
/>
|
|
225
|
-
))}
|
|
226
|
-
</Stack>
|
|
227
|
-
</Dialog>
|
|
228
|
-
) : null}
|
|
229
|
-
{props.children}
|
|
230
|
-
</RunInstructionContext.Provider>
|
|
231
|
-
)
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
export function UserInput(props: {
|
|
235
|
-
block: UserInputBlock
|
|
236
|
-
inputs: BlockInputs
|
|
237
|
-
setInputs: Dispatch<SetStateAction<BlockInputs>>
|
|
238
|
-
autoFocus?: boolean
|
|
239
|
-
}) {
|
|
240
|
-
const {block, autoFocus, setInputs, inputs} = props
|
|
241
|
-
const key = block._key
|
|
242
|
-
const textAreaRef = useRef<HTMLTextAreaElement>(null)
|
|
243
|
-
|
|
244
|
-
const onChange = useCallback(
|
|
245
|
-
(e: FormEvent<HTMLTextAreaElement>) => {
|
|
246
|
-
setInputs((current) => ({
|
|
247
|
-
...current,
|
|
248
|
-
[key]: (e.currentTarget ?? e.target).value,
|
|
249
|
-
}))
|
|
250
|
-
},
|
|
251
|
-
[key, setInputs],
|
|
252
|
-
)
|
|
253
|
-
|
|
254
|
-
const value = useMemo(() => inputs[key], [inputs, key])
|
|
255
|
-
|
|
256
|
-
useEffect(() => {
|
|
257
|
-
if (!autoFocus) {
|
|
258
|
-
return
|
|
259
|
-
}
|
|
260
|
-
setTimeout(() => textAreaRef.current?.focus(), 0)
|
|
261
|
-
}, [autoFocus])
|
|
262
|
-
|
|
263
|
-
return (
|
|
264
|
-
<Stack padding={2} space={3}>
|
|
265
|
-
<FormFieldHeaderText
|
|
266
|
-
title={block?.message ?? 'Provide more context'}
|
|
267
|
-
description={block.description}
|
|
268
|
-
/>
|
|
269
|
-
<TextArea
|
|
270
|
-
ref={textAreaRef}
|
|
271
|
-
rows={4}
|
|
272
|
-
value={value}
|
|
273
|
-
onChange={onChange}
|
|
274
|
-
style={{resize: 'vertical'}}
|
|
275
|
-
/>
|
|
276
|
-
</Stack>
|
|
277
|
-
)
|
|
278
|
-
}
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
import {
|
|
2
|
-
asFieldRefsByTypePath,
|
|
3
|
-
FieldRef,
|
|
4
|
-
getFieldRefs as createFieldRefs,
|
|
5
|
-
} from '../assistInspector/helpers'
|
|
6
|
-
import type {ObjectSchemaType} from 'sanity'
|
|
7
|
-
|
|
8
|
-
export function createFieldRefCache() {
|
|
9
|
-
const byType: Record<
|
|
10
|
-
string,
|
|
11
|
-
| {
|
|
12
|
-
fieldRefs: FieldRef[]
|
|
13
|
-
fieldRefsByTypePath: Record<string, FieldRef | undefined>
|
|
14
|
-
}
|
|
15
|
-
| undefined
|
|
16
|
-
> = {}
|
|
17
|
-
|
|
18
|
-
function getRefsForType(schemaType: ObjectSchemaType) {
|
|
19
|
-
const documentType = schemaType.name
|
|
20
|
-
const cached = byType[documentType]
|
|
21
|
-
if (cached) return cached
|
|
22
|
-
|
|
23
|
-
const fieldRefs = createFieldRefs(schemaType)
|
|
24
|
-
const fieldRefsByTypePath = asFieldRefsByTypePath(fieldRefs)
|
|
25
|
-
const refs = {
|
|
26
|
-
fieldRefs,
|
|
27
|
-
fieldRefsByTypePath,
|
|
28
|
-
}
|
|
29
|
-
byType[documentType] = refs
|
|
30
|
-
return refs
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
return getRefsForType
|
|
34
|
-
}
|
package/src/assistTypes.ts
DELETED
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
import {CurrentUser} from 'sanity'
|
|
2
|
-
|
|
3
|
-
export interface AssistConfig {
|
|
4
|
-
/**
|
|
5
|
-
* As of v3.0 Assist can write to date and datetime fields.
|
|
6
|
-
*
|
|
7
|
-
* If this function is omitted from config, the plugin will use the default timeZone and locale
|
|
8
|
-
* in the browser:
|
|
9
|
-
*
|
|
10
|
-
* ```ts
|
|
11
|
-
* const {timeZone, locale} = Intl.DateTimeFormat().resolvedOptions()
|
|
12
|
-
* ```
|
|
13
|
-
*
|
|
14
|
-
* The function will be called any time an instruction runs.
|
|
15
|
-
*
|
|
16
|
-
* @see #LocaleSettings.locale
|
|
17
|
-
* @see #LocaleSettings.timeZone
|
|
18
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#getcanonicalocales
|
|
19
|
-
* @see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
|
20
|
-
*/
|
|
21
|
-
localeSettings?: (context: LocaleSettingsContext) => LocaleSettings
|
|
22
|
-
|
|
23
|
-
/**
|
|
24
|
-
* The max depth for document paths AI Assist will write to.
|
|
25
|
-
*
|
|
26
|
-
* Depth is based on field path segments:
|
|
27
|
-
* - `title` has depth 1
|
|
28
|
-
* - `array[_key="no"].title` has depth 3
|
|
29
|
-
*
|
|
30
|
-
* Be careful not to set this too high in studios with recursive document schemas, as it could have
|
|
31
|
-
* negative impact on performance.
|
|
32
|
-
*
|
|
33
|
-
* Depth will be counted from the field the instruction is run from. For example, if an instruction
|
|
34
|
-
* is attached to depth 6, the count starts from there (at 0, not at 6).
|
|
35
|
-
*
|
|
36
|
-
* Default: 4
|
|
37
|
-
*/
|
|
38
|
-
maxPathDepth?: number
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Influences how much the output of an instruction will vary.
|
|
42
|
-
*
|
|
43
|
-
* Min: 0 – re-running an instruction will often produce the same outcomes
|
|
44
|
-
* Max: 1 – re-running an instruction can produce wildly different outcomes
|
|
45
|
-
*
|
|
46
|
-
* This parameter applies to _all_ instructions in the studio.
|
|
47
|
-
*
|
|
48
|
-
* Prior to v3.0, this defaulted to 0
|
|
49
|
-
*
|
|
50
|
-
* Default: 0.3
|
|
51
|
-
*/
|
|
52
|
-
temperature?: number
|
|
53
|
-
}
|
|
54
|
-
|
|
55
|
-
export interface LocaleSettingsContext {
|
|
56
|
-
user: CurrentUser
|
|
57
|
-
defaultSettings: LocaleSettings
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
export interface LocaleSettings {
|
|
61
|
-
/**
|
|
62
|
-
* A valid Unicode BCP 47 locale identifier used to interpret and format
|
|
63
|
-
* natural language inputs and date output. Examples include "en-US", "fr-FR", or "ja-JP".
|
|
64
|
-
*
|
|
65
|
-
* This affects how phrases like "next Friday" or "in two weeks" are parsed,
|
|
66
|
-
* and how resulting dates are presented (e.g., 12-hour vs 24-hour format).
|
|
67
|
-
*
|
|
68
|
-
* @see https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#getcanonicalocales
|
|
69
|
-
*/
|
|
70
|
-
locale: string
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* A valid IANA time zone identifier used to resolve relative and absolute
|
|
74
|
-
* date expressions to a specific point in time. Examples include
|
|
75
|
-
* "America/New_York", "Europe/Paris", or "Asia/Tokyo".
|
|
76
|
-
*
|
|
77
|
-
* This ensures phrases like "tomorrow at 9am" are interpreted correctly
|
|
78
|
-
* based on the user's local time.
|
|
79
|
-
*
|
|
80
|
-
* @see https://en.wikipedia.org/wiki/List_of_tz_database_time_zones
|
|
81
|
-
*/
|
|
82
|
-
timeZone: string
|
|
83
|
-
}
|
|
@@ -1,40 +0,0 @@
|
|
|
1
|
-
import {forwardRef, type ReactElement, type ReactNode} from 'react'
|
|
2
|
-
import {keyframes, styled} from 'styled-components'
|
|
3
|
-
|
|
4
|
-
const fadeIn = keyframes`
|
|
5
|
-
0% {
|
|
6
|
-
opacity: 0;
|
|
7
|
-
transform: scale(0.75);
|
|
8
|
-
}
|
|
9
|
-
40% {
|
|
10
|
-
opacity: 0;
|
|
11
|
-
transform: scale(0.75);
|
|
12
|
-
}
|
|
13
|
-
100% {
|
|
14
|
-
opacity: 1;
|
|
15
|
-
transform: scale(1);
|
|
16
|
-
}
|
|
17
|
-
`
|
|
18
|
-
|
|
19
|
-
const FadeInDiv = styled.div`
|
|
20
|
-
animation-name: ${fadeIn};
|
|
21
|
-
animation-timing-function: ease-in-out;
|
|
22
|
-
`
|
|
23
|
-
|
|
24
|
-
export const FadeInContent = forwardRef(function FadeInContent(
|
|
25
|
-
{
|
|
26
|
-
children,
|
|
27
|
-
durationMs = 250,
|
|
28
|
-
}: {
|
|
29
|
-
children?: ReactNode
|
|
30
|
-
ms?: number
|
|
31
|
-
durationMs?: number
|
|
32
|
-
},
|
|
33
|
-
ref: any,
|
|
34
|
-
): ReactElement {
|
|
35
|
-
return (
|
|
36
|
-
<FadeInDiv ref={ref} style={{animationDuration: `${durationMs}ms`}}>
|
|
37
|
-
{children}
|
|
38
|
-
</FadeInDiv>
|
|
39
|
-
)
|
|
40
|
-
})
|
|
@@ -1,25 +0,0 @@
|
|
|
1
|
-
import {Box} from '@sanity/ui'
|
|
2
|
-
import {useEffect, useRef} from 'react'
|
|
3
|
-
import {ObjectInputProps} from 'sanity'
|
|
4
|
-
|
|
5
|
-
export function HideReferenceChangedBannerInput(props: ObjectInputProps) {
|
|
6
|
-
const ref = useRef<HTMLDivElement>(null)
|
|
7
|
-
|
|
8
|
-
// hides "reference was changed" banner (it is incorrectly flashing because the pane handler does not support the way wie use the assist pane)
|
|
9
|
-
useEffect(() => {
|
|
10
|
-
const parent = ref.current?.closest('[data-testid="pane-content"]')
|
|
11
|
-
if (!parent) {
|
|
12
|
-
return
|
|
13
|
-
}
|
|
14
|
-
const style = document.createElement('style')
|
|
15
|
-
const parentId = `id-${Math.random()}`.replace('.', '-')
|
|
16
|
-
parent.id = parentId
|
|
17
|
-
|
|
18
|
-
style.innerText = `
|
|
19
|
-
#${parentId} [data-testid="reference-changed-banner"] { display: none; }
|
|
20
|
-
`
|
|
21
|
-
parent.prepend(style)
|
|
22
|
-
}, [ref])
|
|
23
|
-
|
|
24
|
-
return <Box ref={ref}>{props.renderDefault(props)}</Box>
|
|
25
|
-
}
|
|
@@ -1,85 +0,0 @@
|
|
|
1
|
-
import {createContext, useEffect, useMemo, useState} from 'react'
|
|
2
|
-
import {getPublishedId, type InputProps, pathToString, usePerspective, useSyncState} from 'sanity'
|
|
3
|
-
import {usePaneRouter} from 'sanity/structure'
|
|
4
|
-
|
|
5
|
-
import {useAssistDocumentContext} from '../assistDocument/AssistDocumentContext'
|
|
6
|
-
import {useAiAssistanceConfig} from '../assistLayout/AiAssistanceConfigContext'
|
|
7
|
-
import {getDescriptionFieldOption, getImageInstructionFieldOption} from '../helpers/typeUtils'
|
|
8
|
-
import {canUseAssist, useApiClient, useGenerateCaption} from '../useApiClient'
|
|
9
|
-
|
|
10
|
-
export interface ImageContextValue {
|
|
11
|
-
imageDescriptionPath?: string
|
|
12
|
-
imageInstructionPath?: string
|
|
13
|
-
assetRef?: string
|
|
14
|
-
}
|
|
15
|
-
|
|
16
|
-
export const ImageContext = createContext<ImageContextValue>({})
|
|
17
|
-
|
|
18
|
-
export function ImageContextProvider(props: InputProps) {
|
|
19
|
-
const {schemaType, path, value, readOnly} = props
|
|
20
|
-
const assetRef = (value as any)?.asset?._ref
|
|
21
|
-
const {selectedReleaseId} = usePerspective()
|
|
22
|
-
const [assetRefState, setAssetRefState] = useState<string | undefined>(assetRef)
|
|
23
|
-
|
|
24
|
-
const {assistableDocumentId, documentSchemaType} = useAssistDocumentContext()
|
|
25
|
-
const {config, status} = useAiAssistanceConfig()
|
|
26
|
-
const apiClient = useApiClient(config?.__customApiClient)
|
|
27
|
-
const {generateCaption} = useGenerateCaption(apiClient)
|
|
28
|
-
|
|
29
|
-
const {isSyncing} = useSyncState(
|
|
30
|
-
getPublishedId(assistableDocumentId),
|
|
31
|
-
documentSchemaType.name,
|
|
32
|
-
selectedReleaseId,
|
|
33
|
-
)
|
|
34
|
-
|
|
35
|
-
const router = usePaneRouter()
|
|
36
|
-
const isShowingOlderRevision = !!router.params?.rev
|
|
37
|
-
|
|
38
|
-
useEffect(() => {
|
|
39
|
-
const descriptionField = getDescriptionFieldOption(schemaType)
|
|
40
|
-
if (
|
|
41
|
-
assetRef &&
|
|
42
|
-
assistableDocumentId &&
|
|
43
|
-
descriptionField?.updateOnImageChange &&
|
|
44
|
-
assetRef !== assetRefState &&
|
|
45
|
-
!isSyncing &&
|
|
46
|
-
!isShowingOlderRevision &&
|
|
47
|
-
!readOnly
|
|
48
|
-
) {
|
|
49
|
-
setAssetRefState(assetRef)
|
|
50
|
-
if (canUseAssist(status)) {
|
|
51
|
-
generateCaption({
|
|
52
|
-
path: pathToString([...path, descriptionField.path]),
|
|
53
|
-
documentId: assistableDocumentId,
|
|
54
|
-
})
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
}, [
|
|
58
|
-
schemaType,
|
|
59
|
-
path,
|
|
60
|
-
assetRef,
|
|
61
|
-
assetRefState,
|
|
62
|
-
assistableDocumentId,
|
|
63
|
-
generateCaption,
|
|
64
|
-
isSyncing,
|
|
65
|
-
status,
|
|
66
|
-
readOnly,
|
|
67
|
-
isShowingOlderRevision,
|
|
68
|
-
])
|
|
69
|
-
|
|
70
|
-
const context: ImageContextValue = useMemo(() => {
|
|
71
|
-
const descriptionField = getDescriptionFieldOption(schemaType)
|
|
72
|
-
const imageInstructionField = getImageInstructionFieldOption(schemaType)
|
|
73
|
-
return {
|
|
74
|
-
imageDescriptionPath: descriptionField?.path
|
|
75
|
-
? pathToString([...path, descriptionField.path])
|
|
76
|
-
: undefined,
|
|
77
|
-
imageInstructionPath: imageInstructionField
|
|
78
|
-
? pathToString([...path, imageInstructionField])
|
|
79
|
-
: undefined,
|
|
80
|
-
assetRef,
|
|
81
|
-
}
|
|
82
|
-
}, [schemaType, path, assetRef])
|
|
83
|
-
|
|
84
|
-
return <ImageContext.Provider value={context}>{props.renderDefault(props)}</ImageContext.Provider>
|
|
85
|
-
}
|
|
@@ -1,74 +0,0 @@
|
|
|
1
|
-
import {Box, Button, Card, ErrorBoundary, Flex, Stack, Text} from '@sanity/ui'
|
|
2
|
-
import {type ErrorInfo, type PropsWithChildren, useCallback, useMemo, useState} from 'react'
|
|
3
|
-
import {type InputProps, isArraySchemaType, PatchEvent, unset} from 'sanity'
|
|
4
|
-
import {styled} from 'styled-components'
|
|
5
|
-
|
|
6
|
-
import {isPortableTextArray} from '../helpers/typeUtils'
|
|
7
|
-
|
|
8
|
-
const WrapPreCard = styled(Card)`
|
|
9
|
-
& pre {
|
|
10
|
-
white-space: pre-wrap !important;
|
|
11
|
-
}
|
|
12
|
-
`
|
|
13
|
-
|
|
14
|
-
export function SafeValueInput(props: InputProps) {
|
|
15
|
-
return (
|
|
16
|
-
<ErrorWrapper onChange={props.onChange}>
|
|
17
|
-
<PteValueFixer {...props} />
|
|
18
|
-
</ErrorWrapper>
|
|
19
|
-
)
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
export function ErrorWrapper(
|
|
23
|
-
props: PropsWithChildren<{onChange: (patchEvent: PatchEvent) => void}>,
|
|
24
|
-
) {
|
|
25
|
-
const {onChange} = props
|
|
26
|
-
const [error, setError] = useState<Error | undefined>()
|
|
27
|
-
|
|
28
|
-
const catchError = useCallback((params: {error: Error; info: ErrorInfo}) => {
|
|
29
|
-
setError(params.error)
|
|
30
|
-
}, [])
|
|
31
|
-
|
|
32
|
-
const unsetValue = useCallback(() => {
|
|
33
|
-
onChange(PatchEvent.from(unset()))
|
|
34
|
-
setError(undefined)
|
|
35
|
-
}, [onChange])
|
|
36
|
-
const dismiss = useCallback(() => setError(undefined), [])
|
|
37
|
-
const catcher = <ErrorBoundary onCatch={catchError}>{props.children}</ErrorBoundary>
|
|
38
|
-
|
|
39
|
-
return error ? (
|
|
40
|
-
<Card border tone="critical" padding={2} contentEditable={false}>
|
|
41
|
-
<Stack space={3}>
|
|
42
|
-
<Text muted weight="semibold">
|
|
43
|
-
An error occurred.
|
|
44
|
-
</Text>
|
|
45
|
-
|
|
46
|
-
<WrapPreCard flex={1} padding={2} tone="critical" border>
|
|
47
|
-
{catcher}
|
|
48
|
-
</WrapPreCard>
|
|
49
|
-
|
|
50
|
-
<Flex width="fill" flex={1} gap={3}>
|
|
51
|
-
<Box flex={1}>
|
|
52
|
-
<Button text="Dismiss" onClick={dismiss} tone="primary" />
|
|
53
|
-
</Box>
|
|
54
|
-
<Button text="Unset value" onClick={unsetValue} tone="critical" />
|
|
55
|
-
</Flex>
|
|
56
|
-
</Stack>
|
|
57
|
-
</Card>
|
|
58
|
-
) : (
|
|
59
|
-
catcher
|
|
60
|
-
)
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
function PteValueFixer(props: InputProps) {
|
|
64
|
-
const isPortableText = useMemo(
|
|
65
|
-
() => isArraySchemaType(props.schemaType) && isPortableTextArray(props.schemaType),
|
|
66
|
-
[props.schemaType],
|
|
67
|
-
)
|
|
68
|
-
const value = props.value
|
|
69
|
-
if (isPortableText && value && !(value as any[]).length) {
|
|
70
|
-
return props.renderDefault({...props, value: undefined})
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return props.renderDefault(props)
|
|
74
|
-
}
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
import {formatDistanceToNow} from 'date-fns'
|
|
2
|
-
import {useEffect, useReducer} from 'react'
|
|
3
|
-
|
|
4
|
-
function useInterval(ms: number) {
|
|
5
|
-
const [tick, update] = useReducer((n) => n + 1, 0)
|
|
6
|
-
|
|
7
|
-
useEffect(() => {
|
|
8
|
-
const i = setInterval(update, ms)
|
|
9
|
-
return () => clearInterval(i)
|
|
10
|
-
}, [ms])
|
|
11
|
-
return tick
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
export function TimeAgo({date}: {date?: string}) {
|
|
15
|
-
useInterval(1000)
|
|
16
|
-
const timeSince = formatDistanceToNow(date ? new Date(date) : new Date())
|
|
17
|
-
return <span title={timeSince}>{timeSince} ago</span>
|
|
18
|
-
}
|
package/src/constants.ts
DELETED
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import {minutesToMilliseconds} from 'date-fns'
|
|
2
|
-
|
|
3
|
-
export const releaseAnnouncementUrl =
|
|
4
|
-
'https://www.sanity.io/blog/sanity-ai-assist-announcement?utm_source=sanity-assist-plugin&utm_medium=organic_social&utm_campaign=ai-assist&utm_content='
|
|
5
|
-
|
|
6
|
-
export const instructionGuideUrl =
|
|
7
|
-
'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='
|
|
8
|
-
|
|
9
|
-
export const giveFeedbackUrl = 'https://forms.gle/Kwz7CThxGeA2GiEU8'
|
|
10
|
-
|
|
11
|
-
export const salesUrl =
|
|
12
|
-
'https://www.sanity.io/contact/sales?utm_source=sanity-assist-plugin&utm_medium=organic_social&utm_campaign=ai-assist&utm_content='
|
|
13
|
-
|
|
14
|
-
export const packageName = '@sanity/assist'
|
|
15
|
-
|
|
16
|
-
export const pluginTitle = 'Sanity AI Assist'
|
|
17
|
-
|
|
18
|
-
export const pluginTitleShort = 'AI Assist'
|
|
19
|
-
|
|
20
|
-
export const maxHistoryVisibilityMs = minutesToMilliseconds(30)
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
import {LockIcon} from '@sanity/icons'
|
|
2
|
-
import {Text, Tooltip} from '@sanity/ui'
|
|
3
|
-
|
|
4
|
-
export function PrivateIcon() {
|
|
5
|
-
return (
|
|
6
|
-
<Tooltip
|
|
7
|
-
content={
|
|
8
|
-
<Text size={1} style={{whiteSpace: 'nowrap'}}>
|
|
9
|
-
Only visible to you
|
|
10
|
-
</Text>
|
|
11
|
-
}
|
|
12
|
-
fallbackPlacements={['bottom']}
|
|
13
|
-
padding={2}
|
|
14
|
-
placement="top"
|
|
15
|
-
portal
|
|
16
|
-
>
|
|
17
|
-
<LockIcon />
|
|
18
|
-
</Tooltip>
|
|
19
|
-
)
|
|
20
|
-
}
|