@sanity/assist 1.2.16 → 2.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 +551 -30
- package/dist/index.cjs.mjs +1 -0
- package/dist/index.d.ts +333 -9
- package/dist/index.esm.js +2463 -390
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +2457 -383
- package/dist/index.js.map +1 -1
- package/package.json +12 -11
- package/src/_lib/form/DocumentForm.tsx +2 -1
- package/src/_lib/form/constants.ts +1 -0
- package/src/assistDocument/AssistDocumentInput.tsx +24 -4
- package/src/assistDocument/RequestRunInstructionProvider.tsx +37 -21
- package/src/assistDocument/components/AssistDocumentForm.tsx +65 -21
- package/src/assistDocument/components/instruction/InstructionInput.tsx +5 -4
- package/src/assistDocument/components/instruction/InstructionOutputField.tsx +45 -0
- package/src/assistDocument/components/instruction/InstructionOutputInput.tsx +205 -0
- package/src/assistDocument/hooks/useStudioAssistDocument.ts +5 -32
- package/src/assistFormComponents/AssistField.tsx +11 -5
- package/src/assistFormComponents/AssistFormBlock.tsx +2 -3
- package/src/assistFormComponents/validation/listItem.tsx +2 -2
- package/src/assistInspector/AssistInspector.tsx +6 -0
- package/src/assistInspector/FieldAutocomplete.tsx +1 -0
- package/src/assistInspector/helpers.ts +9 -11
- package/src/assistLayout/AssistLayout.tsx +9 -9
- package/src/components/ImageContext.tsx +30 -13
- package/src/components/SafeValueInput.tsx +4 -1
- package/src/fieldActions/assistFieldActions.tsx +42 -13
- package/src/fieldActions/generateCaptionActions.tsx +17 -6
- package/src/fieldActions/generateImageActions.tsx +57 -0
- package/src/helpers/assistSupported.ts +10 -16
- package/src/helpers/conditionalMembers.test.ts +200 -0
- package/src/helpers/conditionalMembers.ts +127 -0
- package/src/helpers/misc.ts +8 -4
- package/src/helpers/typeUtils.ts +19 -5
- package/src/index.ts +3 -0
- package/src/plugin.tsx +18 -4
- package/src/schemas/assistDocumentSchema.tsx +40 -1
- package/src/schemas/serialize/serializeSchema.test.ts +239 -8
- package/src/schemas/serialize/serializeSchema.ts +77 -10
- package/src/schemas/typeDefExtensions.ts +89 -5
- package/src/translate/FieldTranslationProvider.tsx +360 -0
- package/src/translate/getLanguageParams.ts +26 -0
- package/src/translate/languageStore.ts +18 -0
- package/src/translate/paths.test.ts +133 -0
- package/src/translate/paths.ts +175 -0
- package/src/translate/translateActions.tsx +188 -0
- package/src/translate/types.ts +160 -0
- package/src/types.ts +67 -15
- package/src/useApiClient.ts +134 -2
- package/src/assistLayout/AlphaMigration.tsx +0 -310
- package/src/legacy-types.ts +0 -72
package/src/useApiClient.ts
CHANGED
|
@@ -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,8 +29,20 @@ 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
|
|
|
42
|
+
export function canUseAssist(status: InstructStatus | undefined) {
|
|
43
|
+
return status?.enabled && status.initialized && status.validToken
|
|
44
|
+
}
|
|
45
|
+
|
|
30
46
|
export function useApiClient(customApiClient?: (defaultClient: SanityClient) => SanityClient) {
|
|
31
47
|
const client = useClient({apiVersion: '2023-06-05'})
|
|
32
48
|
return useMemo(
|
|
@@ -35,6 +51,69 @@ export function useApiClient(customApiClient?: (defaultClient: SanityClient) =>
|
|
|
35
51
|
)
|
|
36
52
|
}
|
|
37
53
|
|
|
54
|
+
export function useTranslate(apiClient: SanityClient) {
|
|
55
|
+
const [loading, setLoading] = useState(false)
|
|
56
|
+
const user = useCurrentUser()
|
|
57
|
+
const schema = useSchema()
|
|
58
|
+
const types = useMemo(() => serializeSchema(schema, {leanFormat: true}), [schema])
|
|
59
|
+
const toast = useToast()
|
|
60
|
+
|
|
61
|
+
const translate = useCallback(
|
|
62
|
+
({
|
|
63
|
+
documentId,
|
|
64
|
+
languagePath,
|
|
65
|
+
translatePath,
|
|
66
|
+
fieldLanguageMap,
|
|
67
|
+
conditionalMembers,
|
|
68
|
+
}: TranslateRequest) => {
|
|
69
|
+
setLoading(true)
|
|
70
|
+
|
|
71
|
+
return apiClient
|
|
72
|
+
.request({
|
|
73
|
+
method: 'POST',
|
|
74
|
+
url: `/assist/tasks/translate/${apiClient.config().dataset}?projectId=${
|
|
75
|
+
apiClient.config().projectId
|
|
76
|
+
}`,
|
|
77
|
+
body: {
|
|
78
|
+
documentId,
|
|
79
|
+
types,
|
|
80
|
+
languagePath,
|
|
81
|
+
fieldLanguageMap,
|
|
82
|
+
conditionalMembers,
|
|
83
|
+
translatePath:
|
|
84
|
+
translatePath.length === 0 ? documentRootKey : pathToString(translatePath),
|
|
85
|
+
userId: user?.id,
|
|
86
|
+
},
|
|
87
|
+
})
|
|
88
|
+
.catch((e) => {
|
|
89
|
+
toast.push({
|
|
90
|
+
status: 'error',
|
|
91
|
+
title: 'Translate failed',
|
|
92
|
+
description: e.message,
|
|
93
|
+
})
|
|
94
|
+
setLoading(false)
|
|
95
|
+
throw e
|
|
96
|
+
})
|
|
97
|
+
.finally(() => {
|
|
98
|
+
// adding some artificial delay here
|
|
99
|
+
// server responds with 201 then proceeds; we dont need to allow spamming the button
|
|
100
|
+
setTimeout(() => {
|
|
101
|
+
setLoading(false)
|
|
102
|
+
}, 2000)
|
|
103
|
+
})
|
|
104
|
+
},
|
|
105
|
+
[setLoading, apiClient, toast, user, types]
|
|
106
|
+
)
|
|
107
|
+
|
|
108
|
+
return useMemo(
|
|
109
|
+
() => ({
|
|
110
|
+
translate,
|
|
111
|
+
loading,
|
|
112
|
+
}),
|
|
113
|
+
[translate, loading]
|
|
114
|
+
)
|
|
115
|
+
}
|
|
116
|
+
|
|
38
117
|
export function useGenerateCaption(apiClient: SanityClient) {
|
|
39
118
|
const [loading, setLoading] = useState(false)
|
|
40
119
|
const user = useCurrentUser()
|
|
@@ -62,7 +141,7 @@ export function useGenerateCaption(apiClient: SanityClient) {
|
|
|
62
141
|
.catch((e) => {
|
|
63
142
|
toast.push({
|
|
64
143
|
status: 'error',
|
|
65
|
-
title: 'Generate
|
|
144
|
+
title: 'Generate image description failed',
|
|
66
145
|
description: e.message,
|
|
67
146
|
})
|
|
68
147
|
setLoading(false)
|
|
@@ -88,6 +167,59 @@ export function useGenerateCaption(apiClient: SanityClient) {
|
|
|
88
167
|
)
|
|
89
168
|
}
|
|
90
169
|
|
|
170
|
+
export function useGenerateImage(apiClient: SanityClient) {
|
|
171
|
+
const [loading, setLoading] = useState(false)
|
|
172
|
+
const user = useCurrentUser()
|
|
173
|
+
const schema = useSchema()
|
|
174
|
+
const types = useMemo(() => serializeSchema(schema, {leanFormat: true}), [schema])
|
|
175
|
+
const toast = useToast()
|
|
176
|
+
|
|
177
|
+
const generateImage = useCallback(
|
|
178
|
+
({path, documentId}: {path: string; documentId: string}) => {
|
|
179
|
+
setLoading(true)
|
|
180
|
+
|
|
181
|
+
return apiClient
|
|
182
|
+
.request({
|
|
183
|
+
method: 'POST',
|
|
184
|
+
url: `/assist/tasks/generate-image/${apiClient.config().dataset}?projectId=${
|
|
185
|
+
apiClient.config().projectId
|
|
186
|
+
}`,
|
|
187
|
+
body: {
|
|
188
|
+
path,
|
|
189
|
+
documentId,
|
|
190
|
+
types,
|
|
191
|
+
userId: user?.id,
|
|
192
|
+
},
|
|
193
|
+
})
|
|
194
|
+
.catch((e) => {
|
|
195
|
+
toast.push({
|
|
196
|
+
status: 'error',
|
|
197
|
+
title: 'Generate image from prompt failed',
|
|
198
|
+
description: e.message,
|
|
199
|
+
})
|
|
200
|
+
setLoading(false)
|
|
201
|
+
throw e
|
|
202
|
+
})
|
|
203
|
+
.finally(() => {
|
|
204
|
+
// adding some artificial delay here
|
|
205
|
+
// server responds with 201 then proceeds; we dont need to allow spamming the button
|
|
206
|
+
setTimeout(() => {
|
|
207
|
+
setLoading(false)
|
|
208
|
+
}, 2000)
|
|
209
|
+
})
|
|
210
|
+
},
|
|
211
|
+
[setLoading, apiClient, toast, user, types]
|
|
212
|
+
)
|
|
213
|
+
|
|
214
|
+
return useMemo(
|
|
215
|
+
() => ({
|
|
216
|
+
generateImage,
|
|
217
|
+
loading,
|
|
218
|
+
}),
|
|
219
|
+
[generateImage, loading]
|
|
220
|
+
)
|
|
221
|
+
}
|
|
222
|
+
|
|
91
223
|
export function useGetInstructStatus(apiClient: SanityClient) {
|
|
92
224
|
const [loading, setLoading] = useState(true)
|
|
93
225
|
|
|
@@ -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
|
-
}
|
package/src/legacy-types.ts
DELETED
|
@@ -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
|
-
}
|