@sanity/assist 1.2.16 → 2.0.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.
Files changed (50) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +551 -30
  3. package/dist/index.cjs.mjs +1 -0
  4. package/dist/index.d.ts +253 -11
  5. package/dist/index.esm.js +2385 -373
  6. package/dist/index.esm.js.map +1 -1
  7. package/dist/index.js +2379 -366
  8. package/dist/index.js.map +1 -1
  9. package/package.json +10 -9
  10. package/src/_lib/form/DocumentForm.tsx +2 -1
  11. package/src/_lib/form/constants.ts +1 -0
  12. package/src/assistDocument/AssistDocumentInput.tsx +24 -4
  13. package/src/assistDocument/RequestRunInstructionProvider.tsx +37 -21
  14. package/src/assistDocument/components/instruction/InstructionInput.tsx +5 -4
  15. package/src/assistDocument/components/instruction/InstructionOutputField.tsx +45 -0
  16. package/src/assistDocument/components/instruction/InstructionOutputInput.tsx +205 -0
  17. package/src/assistDocument/hooks/useStudioAssistDocument.ts +5 -32
  18. package/src/assistFormComponents/AssistField.tsx +11 -5
  19. package/src/assistFormComponents/AssistFormBlock.tsx +2 -3
  20. package/src/assistFormComponents/validation/listItem.tsx +2 -2
  21. package/src/assistInspector/AssistInspector.tsx +6 -0
  22. package/src/assistInspector/FieldAutocomplete.tsx +1 -0
  23. package/src/assistInspector/helpers.ts +9 -11
  24. package/src/assistLayout/AssistLayout.tsx +9 -9
  25. package/src/components/ImageContext.tsx +19 -9
  26. package/src/components/SafeValueInput.tsx +4 -1
  27. package/src/fieldActions/assistFieldActions.tsx +42 -13
  28. package/src/fieldActions/generateCaptionActions.tsx +2 -2
  29. package/src/fieldActions/generateImageActions.tsx +57 -0
  30. package/src/helpers/assistSupported.ts +10 -16
  31. package/src/helpers/conditionalMembers.test.ts +200 -0
  32. package/src/helpers/conditionalMembers.ts +127 -0
  33. package/src/helpers/typeUtils.ts +19 -5
  34. package/src/index.ts +3 -0
  35. package/src/plugin.tsx +14 -5
  36. package/src/schemas/assistDocumentSchema.tsx +40 -1
  37. package/src/schemas/serialize/serializeSchema.test.ts +239 -8
  38. package/src/schemas/serialize/serializeSchema.ts +77 -10
  39. package/src/schemas/typeDefExtensions.ts +89 -5
  40. package/src/translate/FieldTranslationProvider.tsx +360 -0
  41. package/src/translate/getLanguageParams.ts +26 -0
  42. package/src/translate/languageStore.ts +18 -0
  43. package/src/translate/paths.test.ts +133 -0
  44. package/src/translate/paths.ts +175 -0
  45. package/src/translate/translateActions.tsx +188 -0
  46. package/src/translate/types.ts +160 -0
  47. package/src/types.ts +33 -12
  48. package/src/useApiClient.ts +130 -2
  49. package/src/assistLayout/AlphaMigration.tsx +0 -310
  50. package/src/legacy-types.ts +0 -72
package/src/types.ts CHANGED
@@ -1,4 +1,4 @@
1
- import {SanityDocument, ValidationMarker} from 'sanity'
1
+ import {SanityDocument} from 'sanity'
2
2
  import {PortableTextBlock, PortableTextMarkDefinition, PortableTextSpan} from '@portabletext/types'
3
3
 
4
4
  //id prefixes
@@ -26,6 +26,9 @@ export const fieldPresenceTypeName = 'sanity.assist.instructionTask.presence' as
26
26
  export const assistSerializedTypeName = 'sanity.assist.serialized.type' as const
27
27
  export const assistSerializedFieldTypeName = 'sanity.assist.serialized.field' as const
28
28
 
29
+ export const outputFieldTypeName = 'sanity.assist.output.field' as const
30
+ export const outputTypeTypeName = 'sanity.assist.output.type' as const
31
+
29
32
  //url params
30
33
  export const inspectParam = 'inspect' as const
31
34
  export const fieldPathParam = 'pathKey' as const
@@ -34,27 +37,29 @@ export const instructionParam = 'instruction' as const
34
37
  // other constants
35
38
  export const documentRootKey = '<document>'
36
39
 
37
- export interface SerializedSchemaMember {
40
+ export type SerializedSchemaMember = Omit<SerializedSchemaType, 'name' | '_type'> & {
38
41
  _type?: typeof assistSerializedFieldTypeName
39
- type: string
40
- name: string
41
- title?: string
42
- values?: string[]
43
- of?: SerializedSchemaMember[]
44
- to?: {type: string}[]
42
+ name?: string
45
43
  }
46
44
 
47
45
  export interface SerializedSchemaType {
48
46
  _type?: typeof assistSerializedTypeName
49
47
  _id?: string
50
48
  type: string
49
+ name: string
51
50
  title?: string
52
- name?: string
53
51
  fields?: SerializedSchemaMember[]
54
- of?: {type: string}[]
55
- to?: {type: string}[]
52
+ of?: SerializedSchemaMember[]
53
+ to?: SerializedSchemaMember[]
54
+ annotations?: SerializedSchemaMember[]
55
+ inlineOf?: SerializedSchemaMember[]
56
+ values?: string[] | {value: string; title?: string}[]
57
+ hidden?: boolean | 'function'
58
+ readOnly?: boolean | 'function'
56
59
  options?: {
60
+ /** equivalent to options.aiAssist.imageDescriptionField - not renamed in the api for backwards compatability */
57
61
  imagePromptField?: string
62
+ embeddingsIndex?: string
58
63
  }
59
64
  }
60
65
 
@@ -149,10 +154,10 @@ export interface StudioInstruction {
149
154
  userId?: string
150
155
  title?: string
151
156
  placeholder?: string
157
+ output?: (OutputFieldItem | OutputTypeItem)[]
152
158
 
153
159
  //added after query / synthetic fields
154
160
  tasks?: InstructionTask[]
155
- validation?: ValidationMarker[]
156
161
  }
157
162
 
158
163
  export interface AssistTasksStatus {
@@ -166,3 +171,19 @@ export interface AssistInspectorRouteParams {
166
171
  [fieldPathParam]?: string
167
172
  [instructionParam]?: string
168
173
  }
174
+
175
+ export interface OutputFieldItem {
176
+ _type: typeof outputFieldTypeName
177
+ _key: string
178
+ //path relative to the field the instruction is for (same as _key)
179
+ relativePath?: string
180
+ }
181
+
182
+ export interface OutputTypeItem {
183
+ _type: typeof outputTypeTypeName
184
+ _key: string
185
+ /* array item type name */
186
+ type?: string
187
+ //path relative to the array-field the instruction is for, can be empty string (the array itself, same as _key)
188
+ relativePath?: string
189
+ }
@@ -1,8 +1,11 @@
1
- import {useClient, useCurrentUser, useSchema} from 'sanity'
1
+ import {Path, pathToString, useClient, useCurrentUser, useSchema} from 'sanity'
2
2
  import {useCallback, useMemo, useState} from 'react'
3
3
  import {serializeSchema} from './schemas/serialize/serializeSchema'
4
4
  import {useToast} from '@sanity/ui'
5
5
  import {SanityClient} from '@sanity/client'
6
+ import {FieldLanguageMap} from './translate/paths'
7
+ import {documentRootKey} from './types'
8
+ import {ConditionalMemberState} from './helpers/conditionalMembers'
6
9
 
7
10
  export interface UserTextInstance {
8
11
  blockKey: string
@@ -17,6 +20,7 @@ export interface RunInstructionRequest {
17
20
  instructionKey: string
18
21
  userId?: string
19
22
  userTexts?: UserTextInstance[]
23
+ conditionalMembers?: ConditionalMemberState[]
20
24
  }
21
25
 
22
26
  export interface InstructStatus {
@@ -25,6 +29,14 @@ export interface InstructStatus {
25
29
  validToken: boolean
26
30
  }
27
31
 
32
+ export interface TranslateRequest {
33
+ documentId: string
34
+ translatePath: Path
35
+ languagePath?: string
36
+ fieldLanguageMap?: FieldLanguageMap[]
37
+ conditionalMembers?: ConditionalMemberState[]
38
+ }
39
+
28
40
  const basePath = '/assist/tasks/instruction'
29
41
 
30
42
  export function useApiClient(customApiClient?: (defaultClient: SanityClient) => SanityClient) {
@@ -35,6 +47,69 @@ export function useApiClient(customApiClient?: (defaultClient: SanityClient) =>
35
47
  )
36
48
  }
37
49
 
50
+ export function useTranslate(apiClient: SanityClient) {
51
+ const [loading, setLoading] = useState(false)
52
+ const user = useCurrentUser()
53
+ const schema = useSchema()
54
+ const types = useMemo(() => serializeSchema(schema, {leanFormat: true}), [schema])
55
+ const toast = useToast()
56
+
57
+ const translate = useCallback(
58
+ ({
59
+ documentId,
60
+ languagePath,
61
+ translatePath,
62
+ fieldLanguageMap,
63
+ conditionalMembers,
64
+ }: TranslateRequest) => {
65
+ setLoading(true)
66
+
67
+ return apiClient
68
+ .request({
69
+ method: 'POST',
70
+ url: `/assist/tasks/translate/${apiClient.config().dataset}?projectId=${
71
+ apiClient.config().projectId
72
+ }`,
73
+ body: {
74
+ documentId,
75
+ types,
76
+ languagePath,
77
+ fieldLanguageMap,
78
+ conditionalMembers,
79
+ translatePath:
80
+ translatePath.length === 0 ? documentRootKey : pathToString(translatePath),
81
+ userId: user?.id,
82
+ },
83
+ })
84
+ .catch((e) => {
85
+ toast.push({
86
+ status: 'error',
87
+ title: 'Translate failed',
88
+ description: e.message,
89
+ })
90
+ setLoading(false)
91
+ throw e
92
+ })
93
+ .finally(() => {
94
+ // adding some artificial delay here
95
+ // server responds with 201 then proceeds; we dont need to allow spamming the button
96
+ setTimeout(() => {
97
+ setLoading(false)
98
+ }, 2000)
99
+ })
100
+ },
101
+ [setLoading, apiClient, toast, user, types]
102
+ )
103
+
104
+ return useMemo(
105
+ () => ({
106
+ translate,
107
+ loading,
108
+ }),
109
+ [translate, loading]
110
+ )
111
+ }
112
+
38
113
  export function useGenerateCaption(apiClient: SanityClient) {
39
114
  const [loading, setLoading] = useState(false)
40
115
  const user = useCurrentUser()
@@ -62,7 +137,7 @@ export function useGenerateCaption(apiClient: SanityClient) {
62
137
  .catch((e) => {
63
138
  toast.push({
64
139
  status: 'error',
65
- title: 'Generate caption failed',
140
+ title: 'Generate image description failed',
66
141
  description: e.message,
67
142
  })
68
143
  setLoading(false)
@@ -88,6 +163,59 @@ export function useGenerateCaption(apiClient: SanityClient) {
88
163
  )
89
164
  }
90
165
 
166
+ export function useGenerateImage(apiClient: SanityClient) {
167
+ const [loading, setLoading] = useState(false)
168
+ const user = useCurrentUser()
169
+ const schema = useSchema()
170
+ const types = useMemo(() => serializeSchema(schema, {leanFormat: true}), [schema])
171
+ const toast = useToast()
172
+
173
+ const generateImage = useCallback(
174
+ ({path, documentId}: {path: string; documentId: string}) => {
175
+ setLoading(true)
176
+
177
+ return apiClient
178
+ .request({
179
+ method: 'POST',
180
+ url: `/assist/tasks/generate-image/${apiClient.config().dataset}?projectId=${
181
+ apiClient.config().projectId
182
+ }`,
183
+ body: {
184
+ path,
185
+ documentId,
186
+ types,
187
+ userId: user?.id,
188
+ },
189
+ })
190
+ .catch((e) => {
191
+ toast.push({
192
+ status: 'error',
193
+ title: 'Generate image from prompt failed',
194
+ description: e.message,
195
+ })
196
+ setLoading(false)
197
+ throw e
198
+ })
199
+ .finally(() => {
200
+ // adding some artificial delay here
201
+ // server responds with 201 then proceeds; we dont need to allow spamming the button
202
+ setTimeout(() => {
203
+ setLoading(false)
204
+ }, 2000)
205
+ })
206
+ },
207
+ [setLoading, apiClient, toast, user, types]
208
+ )
209
+
210
+ return useMemo(
211
+ () => ({
212
+ generateImage,
213
+ loading,
214
+ }),
215
+ [generateImage, loading]
216
+ )
217
+ }
218
+
91
219
  export function useGetInstructStatus(apiClient: SanityClient) {
92
220
  const [loading, setLoading] = useState(true)
93
221
 
@@ -1,310 +0,0 @@
1
- import {SanityClient, SanityDocument, useClient} from 'sanity'
2
- import {useCallback, useEffect, useState} from 'react'
3
- import {Box, Button, Card, Dialog, Spinner, Stack, Text, useToast} from '@sanity/ui'
4
- import {CheckmarkIcon} from '@sanity/icons'
5
- import {
6
- LegacyAssistDocument,
7
- legacyAssistDocumentIdPrefix,
8
- legacyAssistDocumentTypeName,
9
- legacyAssistStatusDocumentTypeName,
10
- LegacyContextBlock,
11
- legacyContextDocumentTypeName,
12
- LegacyFieldRef,
13
- LegacyPromptBlock,
14
- LegacyPromptTextBlock,
15
- LegacyUserInputBlock,
16
- } from '../legacy-types'
17
- import {assistDocumentId} from '../helpers/ids'
18
- import {
19
- assistDocumentIdPrefix,
20
- assistDocumentTypeName,
21
- AssistField,
22
- assistFieldTypeName,
23
- contextDocumentTypeName,
24
- fieldReferenceTypeName,
25
- InlinePromptBlock,
26
- instructionContextTypeName,
27
- instructionTypeName,
28
- PromptBlock,
29
- userInputTypeName,
30
- } from '../types'
31
- import {PortableTextSpan} from '@portabletext/types'
32
- import {pluginTitle} from '../constants'
33
-
34
- const NO_ASSIST_DOCS: LegacyAssistDocument[] = []
35
- const NO_CONTEXT_DOCS: SanityDocument[] = []
36
- const NO_IDS: string[] = []
37
-
38
- interface MigratedContextDoc {
39
- _id: string
40
- _alphaId: string
41
- }
42
-
43
- type Task = (subtaskProgress: (percentage: number) => void) => Promise<void>
44
-
45
- export function AlphaMigration() {
46
- const [alphaAssistDocs, setAlphaAssistDocs] = useState(NO_ASSIST_DOCS)
47
- const [contextDocs, setContextDocs] = useState(NO_CONTEXT_DOCS)
48
- const [staleStatusDocIds, setStaleStatusDocs] = useState(NO_IDS)
49
- const [error, setError] = useState<Error | undefined>(undefined)
50
- const [progress, setProgress] = useState<number | undefined>(undefined)
51
- const toast = useToast()
52
- const client = useClient({apiVersion: '2023-06-01'})
53
-
54
- useEffect(() => {
55
- let canUpdate = true
56
- client
57
- .fetch<{
58
- assistDocs?: LegacyAssistDocument[]
59
- staleStatusDocIds?: string[]
60
- contextDocs?: SanityDocument[]
61
- }>(
62
- `
63
- {
64
- "assistDocs": *[_type=="${legacyAssistDocumentTypeName}"],
65
- "staleStatusDocIds": *[_type=="${legacyAssistStatusDocumentTypeName}"]._id,
66
- "contextDocs": *[_type=="${legacyContextDocumentTypeName}"],
67
- }
68
- `
69
- )
70
- .then((result) => {
71
- if (!canUpdate || !result) {
72
- return
73
- }
74
- setAlphaAssistDocs(result?.assistDocs ?? NO_ASSIST_DOCS)
75
- setStaleStatusDocs(result?.staleStatusDocIds ?? NO_IDS)
76
- setContextDocs(result?.contextDocs ?? NO_CONTEXT_DOCS)
77
- })
78
- return () => {
79
- canUpdate = false
80
- }
81
- }, [client, setAlphaAssistDocs, setStaleStatusDocs, setContextDocs])
82
-
83
- const convert = useCallback(async () => {
84
- try {
85
- setProgress(0.0001)
86
-
87
- const tasks: Task[] = [
88
- () => convertContextDocs(client, contextDocs),
89
- (subtaskProgress) => deleteDocs(client, staleStatusDocIds, subtaskProgress),
90
- (subtaskProgress) => convertDocs(client, alphaAssistDocs, subtaskProgress),
91
- (subtaskProgress) =>
92
- deleteDocs(
93
- client,
94
- contextDocs.map((d) => d._id),
95
- subtaskProgress
96
- ),
97
- ]
98
-
99
- const taskSize = 1 / tasks.length
100
- for (let i = 0; i < tasks.length; i++) {
101
- const startProgress = i / tasks.length
102
- await tasks[i]((subProgress) => setProgress(startProgress + subProgress * taskSize))
103
- setProgress((i + 1) / tasks.length)
104
- }
105
-
106
- setProgress(1)
107
- setAlphaAssistDocs(NO_ASSIST_DOCS)
108
- setContextDocs(NO_CONTEXT_DOCS)
109
- setStaleStatusDocs(NO_IDS)
110
- toast.push({
111
- title: `Converted instructions to new format.`,
112
- status: 'success',
113
- closable: true,
114
- })
115
- } catch (e: any) {
116
- console.error(e)
117
- toast.push({
118
- title: `An error occurred`,
119
- status: 'error',
120
- closable: true,
121
- })
122
- setError(e)
123
- setProgress(undefined)
124
- }
125
- }, [contextDocs, client, alphaAssistDocs, staleStatusDocIds, setProgress, toast])
126
-
127
- if (
128
- (alphaAssistDocs.length || staleStatusDocIds.length || contextDocs.length) &&
129
- (!progress || progress < 1)
130
- ) {
131
- return (
132
- <Dialog id="outdated-assist-docs" header={pluginTitle}>
133
- <Card padding={3}>
134
- <Stack space={4} style={{maxWidth: 500}}>
135
- <Text size={1}>
136
- It seems like this workspace contains documents from an{' '}
137
- <strong>older version of {pluginTitle}</strong>.
138
- </Text>
139
- <Text size={1}>Cleanup is required.</Text>
140
- {error ? (
141
- <Card padding={2} tone="critical" border>
142
- <Text size={1}>An error occurred. See console for details.</Text>{' '}
143
- </Card>
144
- ) : null}
145
- <Button
146
- icon={
147
- progress ? (
148
- <Box style={{marginTop: 5}}>
149
- <Spinner />
150
- </Box>
151
- ) : (
152
- CheckmarkIcon
153
- )
154
- }
155
- disabled={!!progress}
156
- text={progress ? `${Math.floor(progress * 100)}%` : 'Ok, convert to new format!'}
157
- tone="primary"
158
- onClick={convert}
159
- />
160
- </Stack>
161
- </Card>
162
- </Dialog>
163
- )
164
- }
165
-
166
- return null
167
- }
168
-
169
- async function deleteDocs(
170
- client: SanityClient,
171
- ids: string[],
172
- updateProgress: (percentage: number) => void
173
- ) {
174
- const chunkSize = 50
175
- for (let i = 0; i < ids.length; i += chunkSize) {
176
- const progressCount = Math.min(ids.length, i + chunkSize)
177
- const chunk = ids.slice(i, progressCount)
178
- const trans = client.transaction()
179
- chunk.forEach((id) => trans.delete(id))
180
- await trans.commit()
181
- updateProgress(progressCount / ids.length)
182
- }
183
- }
184
-
185
- async function convertContextDocs(client: SanityClient, docs: SanityDocument[]) {
186
- const trans = client.transaction()
187
-
188
- for (const doc of docs) {
189
- const {_id, _type, ...rest} = doc
190
- trans.createOrReplace({
191
- ...rest,
192
- _id: `port.${_id}`,
193
- _alphaId: _id,
194
- _type: contextDocumentTypeName,
195
- })
196
- }
197
-
198
- await trans.commit()
199
- }
200
-
201
- async function convertDocs(
202
- client: SanityClient,
203
- docs: LegacyAssistDocument[],
204
- updateProgress: (percentage: number) => void
205
- ) {
206
- const chunkSize = 10
207
- for (let i = 0; i < docs.length; i += chunkSize) {
208
- const progressCount = Math.min(docs.length, i + chunkSize)
209
- const chunk = docs.slice(i, progressCount)
210
-
211
- const trans = client.transaction()
212
- const contextDocs: MigratedContextDoc[] = await client.fetch(
213
- `*[_type=="${contextDocumentTypeName}" && _alphaId != null]{_id, _alphaId}`
214
- )
215
-
216
- chunk.forEach((oldDoc) => {
217
- const documentType = oldDoc._id.replace(
218
- new RegExp(`^(${legacyAssistDocumentIdPrefix}|${assistDocumentIdPrefix})`),
219
- ''
220
- )
221
-
222
- const id = assistDocumentId(documentType)
223
-
224
- const fields: AssistField[] = (oldDoc.fields ?? [])
225
- .filter((field) => field.instructions?.length)
226
- .map((oldField) => {
227
- const instructions = (oldField.instructions ?? []).map((inst) => {
228
- // eslint-disable-next-line max-nested-callbacks
229
- const prompt = (inst.prompt ?? []).map((block) => {
230
- return mapBlock(block, contextDocs) as PromptBlock
231
- })
232
- return {
233
- ...inst,
234
- _type: instructionTypeName,
235
- prompt,
236
- }
237
- })
238
- return {
239
- ...oldField,
240
- _type: assistFieldTypeName,
241
- instructions,
242
- }
243
- })
244
-
245
- if (fields.length) {
246
- trans.createOrReplace({
247
- _id: id,
248
- _type: assistDocumentTypeName,
249
- fields,
250
- })
251
- }
252
- trans.delete(oldDoc._id)
253
- })
254
- await trans.commit()
255
- updateProgress(progressCount / docs.length)
256
- }
257
- }
258
-
259
- type Blocks = LegacyPromptBlock | LegacyPromptTextBlock | PortableTextSpan
260
-
261
- function isFieldRef(block: Blocks): block is LegacyFieldRef {
262
- return block._type === 'sanity.ai.prompt.fieldRef'
263
- }
264
-
265
- function isContext(block: Blocks): block is LegacyContextBlock {
266
- return block._type === 'sanity.ai.prompt.context'
267
- }
268
-
269
- function isUserInput(block: Blocks): block is LegacyUserInputBlock {
270
- return block._type === 'sanity.ai.prompt.userInput'
271
- }
272
-
273
- function isSpan(block: Blocks): block is PortableTextSpan {
274
- return block._type === 'span'
275
- }
276
-
277
- function mapBlock(
278
- block: Blocks,
279
- migratedContexts: MigratedContextDoc[]
280
- ): PromptBlock | InlinePromptBlock {
281
- if (isFieldRef(block)) {
282
- return {...block, _type: fieldReferenceTypeName}
283
- }
284
- if (isUserInput(block)) {
285
- return {...block, _type: userInputTypeName}
286
- }
287
- if (isContext(block)) {
288
- const newBlock = {
289
- ...block,
290
- _type: instructionContextTypeName,
291
- reference: {
292
- _type: 'reference',
293
- _ref:
294
- migratedContexts.find((c) => c._alphaId === block.reference?._ref)?._id ??
295
- block.reference?._ref,
296
- },
297
- } as const
298
- return newBlock
299
- }
300
- if (isSpan(block)) {
301
- return block
302
- }
303
- const textBlock = block
304
- return {
305
- ...textBlock,
306
- children: (textBlock.children ?? []).map(
307
- (child) => mapBlock(child, migratedContexts) as InlinePromptBlock
308
- ),
309
- }
310
- }
@@ -1,72 +0,0 @@
1
- import {SanityDocument} from 'sanity'
2
- import {PortableTextBlock, PortableTextMarkDefinition, PortableTextSpan} from '@portabletext/types'
3
-
4
- //id prefixes
5
- export const legacyAssistDocumentIdPrefix = 'sanity.ai.'
6
-
7
- export const legacyAssistDocumentTypeName = 'sanity.ai.docType' as const
8
- const aiFieldTypeName = 'sanity.ai.docType.field' as const
9
- const instructionTypeName = 'sanity.ai.field.instruction' as const
10
-
11
- const userInputTypeName = 'sanity.ai.prompt.userInput' as const
12
- const promptContextTypeName = 'sanity.ai.prompt.context' as const
13
- const fieldReferenceTypeName = 'sanity.ai.prompt.fieldRef' as const
14
-
15
- export const legacyContextDocumentTypeName = 'ai.instruction.context' as const
16
-
17
- export const legacyAssistStatusDocumentTypeName = 'sanity.ai.instructionStatus' as const
18
-
19
- export interface FieldPrompts {
20
- _key: string
21
- _type: typeof aiFieldTypeName
22
- path?: string
23
- instructions?: LegacyInstruction[]
24
- }
25
-
26
- export interface LegacyAssistDocument extends SanityDocument {
27
- fields: FieldPrompts[]
28
- }
29
-
30
- export interface LegacyFieldRef extends PortableTextMarkDefinition {
31
- _type: typeof fieldReferenceTypeName
32
- path?: string
33
- }
34
-
35
- export interface LegacyContextBlock {
36
- _type: typeof promptContextTypeName
37
- reference?: {
38
- _type: 'reference'
39
- _ref?: string
40
- }
41
- }
42
-
43
- export interface LegacyUserInputBlock {
44
- _type: typeof userInputTypeName
45
- _key: string
46
- message?: string
47
- description?: string
48
- }
49
-
50
- export type LegacyPromptTextBlock = PortableTextBlock<
51
- never,
52
- PortableTextSpan | LegacyFieldRef | LegacyUserInputBlock | LegacyContextBlock,
53
- 'normal',
54
- never
55
- >
56
-
57
- export type LegacyPromptBlock =
58
- | LegacyPromptTextBlock
59
- | LegacyFieldRef
60
- | LegacyContextBlock
61
- | LegacyUserInputBlock
62
-
63
- export interface LegacyInstruction {
64
- _key: string
65
- _type: typeof instructionTypeName
66
- prompt?: LegacyPromptBlock[]
67
-
68
- icon?: string
69
- userId?: string
70
- title?: string
71
- placeholder?: string
72
- }