@sanity/assist 1.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 (109) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +205 -0
  3. package/dist/index.d.ts +52 -0
  4. package/dist/index.esm.js +2341 -0
  5. package/dist/index.esm.js.map +1 -0
  6. package/dist/index.js +2341 -0
  7. package/dist/index.js.map +1 -0
  8. package/package.json +98 -0
  9. package/sanity.json +8 -0
  10. package/src/_lib/connector/ConnectFromRegion.tsx +24 -0
  11. package/src/_lib/connector/ConnectToRegion.tsx +22 -0
  12. package/src/_lib/connector/ConnectorRegion.tsx +23 -0
  13. package/src/_lib/connector/ConnectorsProvider.tsx +19 -0
  14. package/src/_lib/connector/ConnectorsStore.ts +122 -0
  15. package/src/_lib/connector/ConnectorsStoreContext.ts +4 -0
  16. package/src/_lib/connector/helpers.ts +5 -0
  17. package/src/_lib/connector/index.ts +9 -0
  18. package/src/_lib/connector/mapConnectorToLine.ts +83 -0
  19. package/src/_lib/connector/types.ts +56 -0
  20. package/src/_lib/connector/useConnectorsStore.ts +13 -0
  21. package/src/_lib/connector/useRegionRects.ts +141 -0
  22. package/src/_lib/fixedListenQuery.ts +101 -0
  23. package/src/_lib/form/DocumentForm.tsx +197 -0
  24. package/src/_lib/form/helpers.ts +31 -0
  25. package/src/_lib/form/index.ts +1 -0
  26. package/src/_lib/randomKey.ts +29 -0
  27. package/src/_lib/useListeningQuery.ts +61 -0
  28. package/src/_lib/usePrevious.ts +9 -0
  29. package/src/assistConnectors/AssistConnectorsOverlay.tsx +132 -0
  30. package/src/assistConnectors/ConnectorPath.tsx +62 -0
  31. package/src/assistConnectors/draw/arrowPath.ts +9 -0
  32. package/src/assistConnectors/draw/connectorPath.ts +142 -0
  33. package/src/assistConnectors/index.ts +1 -0
  34. package/src/assistDocument/AssistDocumentContext.tsx +31 -0
  35. package/src/assistDocument/AssistDocumentContextProvider.tsx +17 -0
  36. package/src/assistDocument/AssistDocumentInput.tsx +46 -0
  37. package/src/assistDocument/RequestRunInstructionProvider.tsx +50 -0
  38. package/src/assistDocument/components/AssistDocumentForm.tsx +188 -0
  39. package/src/assistDocument/components/FieldRefPreview.tsx +27 -0
  40. package/src/assistDocument/components/InstructionsArrayField.tsx +8 -0
  41. package/src/assistDocument/components/InstructionsArrayInput.tsx +26 -0
  42. package/src/assistDocument/components/SelectedFieldContext.tsx +10 -0
  43. package/src/assistDocument/components/generic/HiddenFieldTitle.tsx +5 -0
  44. package/src/assistDocument/components/helpers.ts +21 -0
  45. package/src/assistDocument/components/instruction/BackToInstructionsLink.tsx +31 -0
  46. package/src/assistDocument/components/instruction/FieldRefInput.tsx +33 -0
  47. package/src/assistDocument/components/instruction/InstructionInput.tsx +87 -0
  48. package/src/assistDocument/components/instruction/PromptInput.tsx +52 -0
  49. package/src/assistDocument/components/instruction/appearance/IconInput.tsx +46 -0
  50. package/src/assistDocument/components/instruction/appearance/InstructionVisibility.tsx +37 -0
  51. package/src/assistDocument/hooks/useAssistDocumentContextValue.tsx +68 -0
  52. package/src/assistDocument/hooks/useDocumentState.ts +6 -0
  53. package/src/assistDocument/hooks/useInstructionToaster.tsx +74 -0
  54. package/src/assistDocument/hooks/useStudioAssistDocument.ts +119 -0
  55. package/src/assistDocument/index.ts +1 -0
  56. package/src/assistFormComponents/AssistField.tsx +51 -0
  57. package/src/assistFormComponents/AssistFormBlock.tsx +31 -0
  58. package/src/assistFormComponents/AssistInlineFormBlock.tsx +14 -0
  59. package/src/assistFormComponents/AssistItem.tsx +20 -0
  60. package/src/assistFormComponents/validation/listItem.tsx +63 -0
  61. package/src/assistFormComponents/validation/validationList.tsx +89 -0
  62. package/src/assistInspector/AssistInspector.tsx +379 -0
  63. package/src/assistInspector/FieldAutocomplete.tsx +119 -0
  64. package/src/assistInspector/InstructionTaskHistoryButton.tsx +261 -0
  65. package/src/assistInspector/constants.ts +1 -0
  66. package/src/assistInspector/helpers.ts +125 -0
  67. package/src/assistInspector/index.ts +26 -0
  68. package/src/assistLayout/AiAssistanceConfigContext.tsx +81 -0
  69. package/src/assistLayout/AlphaMigration.tsx +311 -0
  70. package/src/assistLayout/AssistLayout.tsx +38 -0
  71. package/src/assistLayout/RunInstructionProvider.tsx +222 -0
  72. package/src/components/AssistFeatureBadge.tsx +9 -0
  73. package/src/components/Delay.tsx +25 -0
  74. package/src/components/HideReferenceChangedBannerInput.tsx +25 -0
  75. package/src/components/SafeValueInput.tsx +73 -0
  76. package/src/components/TimeAgo.tsx +18 -0
  77. package/src/constants.ts +20 -0
  78. package/src/fieldActions/PrivateIcon.tsx +20 -0
  79. package/src/fieldActions/assistFieldActions.tsx +230 -0
  80. package/src/globals.d.ts +4 -0
  81. package/src/helpers/assistSupported.ts +44 -0
  82. package/src/helpers/ids.ts +19 -0
  83. package/src/helpers/misc.ts +16 -0
  84. package/src/helpers/typeUtils.ts +15 -0
  85. package/src/helpers/useAssistSupported.ts +10 -0
  86. package/src/index.ts +6 -0
  87. package/src/legacy-types.ts +72 -0
  88. package/src/onboarding/FieldActionsOnboarding.tsx +90 -0
  89. package/src/onboarding/FirstAssistedPathProvider.tsx +29 -0
  90. package/src/onboarding/InspectorOnboarding.tsx +46 -0
  91. package/src/onboarding/onboardingStore.ts +33 -0
  92. package/src/plugin.tsx +80 -0
  93. package/src/presence/AiFieldPresence.tsx +28 -0
  94. package/src/presence/AssistAvatar.tsx +96 -0
  95. package/src/presence/AssistDocumentPresence.tsx +58 -0
  96. package/src/presence/useAssistPresence.ts +61 -0
  97. package/src/schemas/assistDocumentSchema.tsx +450 -0
  98. package/src/schemas/contextDocumentSchema.tsx +56 -0
  99. package/src/schemas/index.ts +25 -0
  100. package/src/schemas/serialize/SchemTypeTool.tsx +102 -0
  101. package/src/schemas/serialize/schemaUtils.ts +37 -0
  102. package/src/schemas/serialize/serializeSchema.test.ts +382 -0
  103. package/src/schemas/serialize/serializeSchema.ts +162 -0
  104. package/src/schemas/serializedSchemaTypeSchema.ts +59 -0
  105. package/src/schemas/typeDefExtensions.ts +30 -0
  106. package/src/types.ts +167 -0
  107. package/src/useApiClient.ts +140 -0
  108. package/src/vite.config.ts +9 -0
  109. package/v2-incompatible.js +11 -0
package/src/types.ts ADDED
@@ -0,0 +1,167 @@
1
+ import {SanityDocument, ValidationMarker} from 'sanity'
2
+ import {PortableTextBlock, PortableTextMarkDefinition, PortableTextSpan} from '@portabletext/types'
3
+
4
+ //id prefixes
5
+ export const assistDocumentIdPrefix = 'sanity.assist.schemaType.'
6
+ export const assistDocumentStatusIdPrefix = 'sanity.assist.status.'
7
+ export const assistSchemaIdPrefix = 'sanity.assist.schema.'
8
+
9
+ // type names
10
+ export const assistDocumentTypeName = 'sanity.assist.schemaType.annotations' as const
11
+ export const assistFieldTypeName = 'sanity.assist.schemaType.field' as const
12
+ export const instructionTypeName = 'sanity.assist.instruction' as const
13
+ export const promptTypeName = 'sanity.assist.instruction.prompt' as const
14
+
15
+ export const userInputTypeName = 'sanity.assist.instruction.userInput' as const
16
+ export const instructionContextTypeName = 'sanity.assist.instruction.context' as const
17
+ export const fieldReferenceTypeName = 'sanity.assist.instruction.fieldRef' as const
18
+
19
+ // user-facing type. Intentionally does not have sanity. prefix
20
+ export const contextDocumentTypeName = 'assist.instruction.context' as const
21
+
22
+ export const assistTasksStatusTypeName = 'sanity.assist.task.status' as const
23
+ export const instructionTaskTypeName = 'sanity.assist.instructionTask' as const
24
+ export const fieldPresenceTypeName = 'sanity.assist.instructionTask.presence' as const
25
+
26
+ export const assistSerializedTypeName = 'sanity.assist.serialized.type' as const
27
+ export const assistSerializedFieldTypeName = 'sanity.assist.serialized.field' as const
28
+
29
+ //url params
30
+ export const inspectParam = 'inspect' as const
31
+ export const fieldPathParam = 'pathKey' as const
32
+ export const instructionParam = 'instruction' as const
33
+
34
+ // other constants
35
+ export const documentRootKey = '<document>'
36
+
37
+ export interface SerializedSchemaMember {
38
+ _type?: typeof assistSerializedFieldTypeName
39
+ type: string
40
+ name: string
41
+ title?: string
42
+ values?: string[]
43
+ of?: SerializedSchemaMember[]
44
+ to?: {type: string}[]
45
+ }
46
+
47
+ export interface SerializedSchemaType {
48
+ _type?: typeof assistSerializedTypeName
49
+ _id?: string
50
+ type: string
51
+ title?: string
52
+ name?: string
53
+ fields?: SerializedSchemaMember[]
54
+ of?: {type: string}[]
55
+ to?: {type: string}[]
56
+ options?: {
57
+ imagePromptField?: string
58
+ }
59
+ }
60
+
61
+ export interface AssistDocument extends SanityDocument {
62
+ fields?: AssistField[]
63
+ instructions?: StudioInstruction[]
64
+ }
65
+
66
+ export interface StudioAssistDocument {
67
+ _id: string
68
+ _type: typeof assistDocumentTypeName
69
+ fields?: StudioAssistField[]
70
+
71
+ // added
72
+ tasks?: InstructionTask[]
73
+ }
74
+ export interface AssistField {
75
+ _key: string
76
+ _type: typeof assistFieldTypeName
77
+ path?: string
78
+ instructions?: StudioInstruction[]
79
+ }
80
+
81
+ export interface StudioAssistField {
82
+ _key: string
83
+ path?: string
84
+ instructions?: StudioInstruction[]
85
+
86
+ // added
87
+ tasks?: InstructionTask[]
88
+ }
89
+
90
+ export interface FieldRef extends PortableTextMarkDefinition {
91
+ _type: typeof fieldReferenceTypeName
92
+ path?: string
93
+ }
94
+
95
+ export interface ContextBlock {
96
+ _type: typeof instructionContextTypeName
97
+ reference?: {
98
+ _type: 'reference'
99
+ _ref?: string
100
+ }
101
+ }
102
+
103
+ export interface UserInputBlock {
104
+ _type: typeof userInputTypeName
105
+ _key: string
106
+ message?: string
107
+ description?: string
108
+ }
109
+
110
+ export type InlinePromptBlock = PortableTextSpan | FieldRef | UserInputBlock | ContextBlock
111
+ export type PromptTextBlock = PortableTextBlock<never, InlinePromptBlock, 'normal', never>
112
+
113
+ export type PromptBlock = PromptTextBlock | FieldRef | ContextBlock | UserInputBlock
114
+
115
+ export interface AiPresence {
116
+ _key: string
117
+ _type: typeof fieldPresenceTypeName
118
+ path?: string
119
+ started?: string
120
+ }
121
+
122
+ export type TaskEndedReason = 'success' | 'error' | 'aborted' | 'timeout'
123
+
124
+ export interface InstructionTask {
125
+ _key: string
126
+ _type: typeof instructionTaskTypeName
127
+ instructionKey?: string
128
+ path?: string
129
+ started?: string
130
+ updated?: string
131
+ ended?: string
132
+ message?: string
133
+ reason?: TaskEndedReason
134
+ presence?: AiPresence[]
135
+ startedByUserId?: string
136
+
137
+ //added by studio
138
+ // eslint-disable-next-line no-use-before-define
139
+ instruction?: StudioInstruction
140
+ }
141
+
142
+ export interface StudioInstruction {
143
+ _key: string
144
+ _type: typeof instructionTypeName
145
+ prompt?: PromptBlock[]
146
+
147
+ icon?: string
148
+ userId?: string
149
+ title?: string
150
+ placeholder?: string
151
+
152
+ //added after query / synthetic fields
153
+ tasks?: InstructionTask[]
154
+ validation?: ValidationMarker[]
155
+ }
156
+
157
+ export interface AssistTasksStatus {
158
+ _id: string
159
+ _type: typeof assistTasksStatusTypeName
160
+ tasks?: InstructionTask[]
161
+ }
162
+
163
+ export interface AssistInspectorRouteParams {
164
+ [inspectParam]?: string
165
+ [fieldPathParam]?: string
166
+ [instructionParam]?: string
167
+ }
@@ -0,0 +1,140 @@
1
+ import {useClient, useCurrentUser, useSchema} from 'sanity'
2
+ import {useCallback, useMemo, useState} from 'react'
3
+ import {serializeSchema} from './schemas/serialize/serializeSchema'
4
+ import {useToast} from '@sanity/ui'
5
+ import {SanityClient} from '@sanity/client'
6
+
7
+ export interface UserTextInstance {
8
+ blockKey: string
9
+ userInput: string
10
+ }
11
+
12
+ export interface RunInstructionRequest {
13
+ documentId: string
14
+ assistDocumentId: string
15
+ path: string
16
+ instructionKey: string
17
+ userId?: string
18
+ userTexts?: UserTextInstance[]
19
+ }
20
+
21
+ export interface InstructStatus {
22
+ enabled: boolean
23
+ initialized: boolean
24
+ validToken: boolean
25
+ }
26
+
27
+ const basePath = '/assist/tasks/instruction'
28
+ const editorialAiFieldActionFeature = 'editorialAiFieldActions'
29
+
30
+ export function useApiClient(customApiClient?: (defaultClient: SanityClient) => SanityClient) {
31
+ const client = useClient({apiVersion: '2023-06-05'})
32
+ return useMemo(
33
+ () => (customApiClient ? customApiClient(client) : client),
34
+ [client, customApiClient]
35
+ )
36
+ }
37
+
38
+ export function useGetInstructStatus(apiClient: SanityClient) {
39
+ const [loading, setLoading] = useState(true)
40
+ const projectClient = useClient({apiVersion: '2023-06-05'})
41
+
42
+ const getInstructStatus = useCallback(async () => {
43
+ setLoading(true)
44
+
45
+ const projectId = apiClient.config().projectId
46
+ try {
47
+ const features = await projectClient.request<string[]>({
48
+ method: 'GET',
49
+ url: `/projects/${projectId}/features`,
50
+ })
51
+
52
+ const enabled = features.some((f) => f === editorialAiFieldActionFeature)
53
+
54
+ const status = await apiClient.request<Omit<InstructStatus, 'enabled'>>({
55
+ method: 'GET',
56
+ url: `${basePath}/${apiClient.config().dataset}/status?projectId=${projectId}`,
57
+ })
58
+
59
+ return {
60
+ ...status,
61
+ enabled,
62
+ }
63
+ } finally {
64
+ setLoading(false)
65
+ }
66
+ }, [setLoading, apiClient, projectClient])
67
+
68
+ return {
69
+ loading,
70
+ getInstructStatus,
71
+ }
72
+ }
73
+
74
+ export function useInitInstruct(apiClient: SanityClient) {
75
+ const [loading, setLoading] = useState(false)
76
+ const initInstruct = useCallback(() => {
77
+ setLoading(true)
78
+ return apiClient
79
+ .request({
80
+ method: 'GET',
81
+ url: `${basePath}/${apiClient.config().dataset}/init?projectId=${
82
+ apiClient.config().projectId
83
+ }`,
84
+ })
85
+ .finally(() => {
86
+ setLoading(false)
87
+ })
88
+ }, [setLoading, apiClient])
89
+
90
+ return {
91
+ loading,
92
+ initInstruct,
93
+ }
94
+ }
95
+
96
+ export function useRunInstructionApi(apiClient: SanityClient) {
97
+ const toast = useToast()
98
+ const [loading, setLoading] = useState(false)
99
+ const user = useCurrentUser()
100
+ const schema = useSchema()
101
+ const types = useMemo(() => serializeSchema(schema, {leanFormat: true}), [schema])
102
+
103
+ const runInstruction = useCallback(
104
+ (request: RunInstructionRequest) => {
105
+ setLoading(true)
106
+ return apiClient
107
+ .request({
108
+ method: 'POST',
109
+ url: `${basePath}/${apiClient.config().dataset}?projectId=${
110
+ apiClient.config().projectId
111
+ }`,
112
+ body: {
113
+ ...request,
114
+ types,
115
+ userId: user?.id,
116
+ },
117
+ })
118
+ .catch((e) => {
119
+ toast.push({
120
+ status: 'error',
121
+ title: 'Instruction failed',
122
+ description: e.message,
123
+ })
124
+ throw e
125
+ })
126
+ .finally(() => {
127
+ setLoading(false)
128
+ })
129
+ },
130
+ [apiClient, types, user, toast]
131
+ )
132
+
133
+ return useMemo(
134
+ () => ({
135
+ runInstruction,
136
+ loading,
137
+ }),
138
+ [runInstruction, loading]
139
+ )
140
+ }
@@ -0,0 +1,9 @@
1
+ import {defineConfig} from 'vitest/config'
2
+
3
+ export default defineConfig({
4
+ test: {},
5
+
6
+ optimizeDeps: {
7
+ disabled: false,
8
+ },
9
+ })
@@ -0,0 +1,11 @@
1
+ const {showIncompatiblePluginDialog} = require('@sanity/incompatible-plugin')
2
+ const {name, version, sanityExchangeUrl} = require('./package.json')
3
+
4
+ export default showIncompatiblePluginDialog({
5
+ name: name,
6
+ versions: {
7
+ v3: version,
8
+ v2: undefined,
9
+ },
10
+ sanityExchangeUrl,
11
+ })