@sanity/assist 5.0.3 → 6.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 (131) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +28 -254
  3. package/dist/index.d.ts +322 -410
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +3182 -2673
  6. package/dist/index.js.map +1 -1
  7. package/package.json +41 -77
  8. package/dist/index.cjs +0 -4264
  9. package/dist/index.cjs.map +0 -1
  10. package/dist/index.d.cts +0 -791
  11. package/sanity.json +0 -8
  12. package/src/_lib/connector/ConnectFromRegion.tsx +0 -25
  13. package/src/_lib/connector/ConnectToRegion.tsx +0 -23
  14. package/src/_lib/connector/ConnectorRegion.tsx +0 -24
  15. package/src/_lib/connector/ConnectorsProvider.tsx +0 -20
  16. package/src/_lib/connector/ConnectorsStore.ts +0 -122
  17. package/src/_lib/connector/ConnectorsStoreContext.ts +0 -5
  18. package/src/_lib/connector/helpers.ts +0 -5
  19. package/src/_lib/connector/index.ts +0 -9
  20. package/src/_lib/connector/mapConnectorToLine.ts +0 -83
  21. package/src/_lib/connector/types.ts +0 -56
  22. package/src/_lib/connector/useConnectorsStore.ts +0 -14
  23. package/src/_lib/connector/useRegionRects.ts +0 -142
  24. package/src/_lib/fixedListenQuery.ts +0 -101
  25. package/src/_lib/form/DocumentForm.tsx +0 -201
  26. package/src/_lib/form/constants.ts +0 -1
  27. package/src/_lib/form/helpers.ts +0 -32
  28. package/src/_lib/form/index.ts +0 -1
  29. package/src/_lib/randomKey.ts +0 -29
  30. package/src/_lib/useListeningQuery.ts +0 -62
  31. package/src/_lib/usePrevious.ts +0 -9
  32. package/src/assistConnectors/AssistConnectorsOverlay.tsx +0 -133
  33. package/src/assistConnectors/ConnectorPath.tsx +0 -63
  34. package/src/assistConnectors/draw/arrowPath.ts +0 -9
  35. package/src/assistConnectors/draw/connectorPath.ts +0 -142
  36. package/src/assistConnectors/index.ts +0 -1
  37. package/src/assistDocument/AssistDocumentContext.tsx +0 -51
  38. package/src/assistDocument/AssistDocumentContextProvider.tsx +0 -17
  39. package/src/assistDocument/AssistDocumentInput.tsx +0 -61
  40. package/src/assistDocument/AssistDocumentLayout.tsx +0 -12
  41. package/src/assistDocument/RequestRunInstructionProvider.tsx +0 -61
  42. package/src/assistDocument/components/AssistDocumentForm.tsx +0 -286
  43. package/src/assistDocument/components/AssistTypeContext.tsx +0 -7
  44. package/src/assistDocument/components/FieldRefPreview.tsx +0 -26
  45. package/src/assistDocument/components/InstructionsArrayField.tsx +0 -8
  46. package/src/assistDocument/components/InstructionsArrayInput.tsx +0 -27
  47. package/src/assistDocument/components/SelectedFieldContext.tsx +0 -10
  48. package/src/assistDocument/components/generic/HiddenFieldTitle.tsx +0 -5
  49. package/src/assistDocument/components/helpers.ts +0 -21
  50. package/src/assistDocument/components/instruction/BackToInstructionsLink.tsx +0 -32
  51. package/src/assistDocument/components/instruction/FieldRefInput.tsx +0 -54
  52. package/src/assistDocument/components/instruction/InstructionInput.tsx +0 -89
  53. package/src/assistDocument/components/instruction/InstructionOutputField.tsx +0 -46
  54. package/src/assistDocument/components/instruction/InstructionOutputInput.tsx +0 -206
  55. package/src/assistDocument/components/instruction/PromptInput.tsx +0 -59
  56. package/src/assistDocument/components/instruction/appearance/IconInput.tsx +0 -46
  57. package/src/assistDocument/components/instruction/appearance/InstructionVisibility.tsx +0 -37
  58. package/src/assistDocument/hooks/useAssistDocumentContextValue.tsx +0 -129
  59. package/src/assistDocument/hooks/useDocumentState.ts +0 -6
  60. package/src/assistDocument/hooks/useInstructionToaster.tsx +0 -75
  61. package/src/assistDocument/hooks/useStudioAssistDocument.ts +0 -99
  62. package/src/assistDocument/index.ts +0 -1
  63. package/src/assistFormComponents/AssistField.tsx +0 -63
  64. package/src/assistFormComponents/AssistFormBlock.tsx +0 -31
  65. package/src/assistFormComponents/AssistInlineFormBlock.tsx +0 -13
  66. package/src/assistFormComponents/AssistItem.tsx +0 -21
  67. package/src/assistFormComponents/validation/listItem.tsx +0 -63
  68. package/src/assistFormComponents/validation/validationList.tsx +0 -90
  69. package/src/assistInspector/AssistInspector.tsx +0 -423
  70. package/src/assistInspector/FieldAutocomplete.tsx +0 -146
  71. package/src/assistInspector/InstructionTaskHistoryButton.tsx +0 -262
  72. package/src/assistInspector/constants.ts +0 -1
  73. package/src/assistInspector/helpers.ts +0 -211
  74. package/src/assistInspector/index.ts +0 -27
  75. package/src/assistLayout/AiAssistanceConfigContext.tsx +0 -32
  76. package/src/assistLayout/AiAssistanceConfigProvider.tsx +0 -98
  77. package/src/assistLayout/AssistLayout.tsx +0 -39
  78. package/src/assistLayout/RunInstructionProvider.tsx +0 -278
  79. package/src/assistLayout/fieldRefCache.tsx +0 -34
  80. package/src/assistTypes.ts +0 -83
  81. package/src/components/AssistFeatureBadge.tsx +0 -9
  82. package/src/components/FadeInContent.tsx +0 -40
  83. package/src/components/HideReferenceChangedBannerInput.tsx +0 -25
  84. package/src/components/ImageContext.tsx +0 -85
  85. package/src/components/SafeValueInput.tsx +0 -74
  86. package/src/components/TimeAgo.tsx +0 -18
  87. package/src/constants.ts +0 -20
  88. package/src/fieldActions/PrivateIcon.tsx +0 -20
  89. package/src/fieldActions/assistFieldActions.tsx +0 -320
  90. package/src/fieldActions/customFieldActions.tsx +0 -333
  91. package/src/fieldActions/generateCaptionActions.tsx +0 -77
  92. package/src/fieldActions/generateImageActions.tsx +0 -58
  93. package/src/fieldActions/useUserInput.ts +0 -107
  94. package/src/globals.d.ts +0 -4
  95. package/src/helpers/assistSupported.ts +0 -49
  96. package/src/helpers/conditionalMembers.test.ts +0 -319
  97. package/src/helpers/conditionalMembers.ts +0 -134
  98. package/src/helpers/ids.test.ts +0 -28
  99. package/src/helpers/ids.ts +0 -23
  100. package/src/helpers/misc.ts +0 -25
  101. package/src/helpers/styleguide.ts +0 -24
  102. package/src/helpers/typeUtils.ts +0 -60
  103. package/src/helpers/useAssistSupported.ts +0 -8
  104. package/src/index.ts +0 -26
  105. package/src/onboarding/FirstAssistedPathProvider.tsx +0 -30
  106. package/src/onboarding/InspectorOnboarding.tsx +0 -47
  107. package/src/onboarding/onboardingStore.ts +0 -32
  108. package/src/plugin.tsx +0 -162
  109. package/src/presence/AiFieldPresence.tsx +0 -28
  110. package/src/presence/AssistAvatar.tsx +0 -96
  111. package/src/presence/AssistDocumentPresence.tsx +0 -50
  112. package/src/presence/useAssistPresence.ts +0 -64
  113. package/src/schemas/assistDocumentSchema.tsx +0 -497
  114. package/src/schemas/contextDocumentSchema.tsx +0 -57
  115. package/src/schemas/index.ts +0 -69
  116. package/src/schemas/serialize/SchemTypeTool.tsx +0 -103
  117. package/src/schemas/serialize/schemaUtils.ts +0 -38
  118. package/src/schemas/serialize/serializeSchema.test.ts +0 -819
  119. package/src/schemas/serialize/serializeSchema.ts +0 -224
  120. package/src/schemas/serializedSchemaTypeSchema.ts +0 -60
  121. package/src/schemas/typeDefExtensions.ts +0 -127
  122. package/src/translate/FieldTranslationProvider.tsx +0 -382
  123. package/src/translate/getLanguageParams.ts +0 -26
  124. package/src/translate/languageStore.ts +0 -18
  125. package/src/translate/paths.test.ts +0 -181
  126. package/src/translate/paths.ts +0 -183
  127. package/src/translate/translateActions.tsx +0 -205
  128. package/src/translate/types.ts +0 -197
  129. package/src/types.ts +0 -220
  130. package/src/useApiClient.ts +0 -338
  131. package/v2-incompatible.js +0 -11
package/README.md CHANGED
@@ -37,20 +37,15 @@
37
37
  - [Define helpers](#define-helpers)
38
38
  - [useUserInput](#useuserinput)
39
39
  - [License](#license)
40
- - [Develop \& test](#develop--test)
41
- - [Release new version](#release-new-version)
42
40
 
43
41
  ## About Sanity AI Assist
44
42
 
45
43
  Free your team to do more of what they’re great at (and less busywork) with the AI assistant that works with structured content. Attach reusable AI instructions to fields and documents to supercharge your editorial workflow.
46
-
47
44
  You create the instructions; Sanity AI Assist does the rest. [Learn more about writing instructions in the Sanity documentation](https://www.sanity.io/docs/ai-assist?utm_source=github.com&utm_medium=organic_social&utm_campaign=ai-assist&utm_content=).
48
-
49
45
  [Read the release announcement here.](https://www.sanity.io/blog/sanity-ai-assist-announcement?utm_source=github.com&utm_medium=organic_social&utm_campaign=ai-assist&utm_content=)
50
46
 
51
47
  > Using this feature requires Sanity to send data to OpenAI.com for processing. It uses generative AI; you should verify the data before using it.
52
-
53
- <img width="1019" alt="Screenshot showing Sanity AI Assist instructions for a title field in the Sanity Studio document editor" src="https://github.com/sanity-io/sanity/assets/835514/4d895477-c6d7-4da0-be25-c73e109edbdb">
48
+ > <img width="1019" alt="Screenshot showing Sanity AI Assist instructions for a title field in the Sanity Studio document editor" src="https://github.com/sanity-io/sanity/assets/835514/4d895477-c6d7-4da0-be25-c73e109edbdb">
54
49
 
55
50
  ## Installation
56
51
 
@@ -72,7 +67,6 @@ In `sanity.config.ts`, add `assist` to the `plugins` array:
72
67
 
73
68
  ```tsx
74
69
  import {assist} from '@sanity/assist'
75
-
76
70
  export default defineConfig({
77
71
  /* other config */
78
72
  plugins: [
@@ -89,31 +83,21 @@ After installing and adding the plugin and having the AI Assist feature enabled
89
83
  - Start the studio and open any document
90
84
  - Click \*the sparkle icon\*\* (✨) in the document header near the close document X-button
91
85
  - Then select **Manage instructions**
92
-
93
- <img width="210" alt="The AI Assist document menu showing 'Manage instructions' highlighted" src="https://github.com/sanity-io/sanity/assets/835514/58c177ca-4530-4f44-abe0-4adcd9e11c8b">
94
-
86
+ <img width="210" alt="The AI Assist document menu showing 'Manage instructions' highlighted" src="https://github.com/sanity-io/sanity/assets/835514/58c177ca-4530-4f44-abe0-4adcd9e11c8b">
95
87
  - Selecting **Manage instructions** will open an inspector panel
96
88
  - Click the **Enable AI assistance** button to create a token and enable AI Assist for everyone with access to the project
97
-
98
- <img width="339" alt="The 'Enable Sanity AI Assist' button" src="https://github.com/sanity-io/sanity/assets/835514/38b81861-6a7c-49a2-a7c5-f46816d0c0a8">
99
-
100
- You will find a new API token entry for your project named “Sanity AI” in your project's API settings on [sanity.io/manage](https://sanity.io/manage).
101
-
102
- <img alt="The Sanity AI Assist API token entry on sanity.io/manage" src="https://github.com/sanity-io/sanity/assets/835514/3b2f549b-926c-4d85-b5fa-dd7f8f58e667" />
103
-
104
- The plugin will now work for any dataset in your project.
105
-
106
- **Note:** You can revoke this token at any time to disable Sanity AI Assist service. A new token has to be generated via the plugin UI for it to work again.
89
+ <img width="339" alt="The 'Enable Sanity AI Assist' button" src="https://github.com/sanity-io/sanity/assets/835514/38b81861-6a7c-49a2-a7c5-f46816d0c0a8">
90
+ You will find a new API token entry for your project named “Sanity AI in your project's API settings on [sanity.io/manage](https://sanity.io/manage).
91
+ <img alt="The Sanity AI Assist API token entry on sanity.io/manage" src="https://github.com/sanity-io/sanity/assets/835514/3b2f549b-926c-4d85-b5fa-dd7f8f58e667" />
92
+ The plugin will now work for any dataset in your project.
93
+ **Note:** You can revoke this token at any time to disable Sanity AI Assist service. A new token has to be generated via the plugin UI for it to work again.
107
94
 
108
95
  ### Permissions
109
96
 
110
97
  If your project is using custom roles (Enterprise), there are some additional considerations.
111
-
112
98
  To see AI Assist presence when running instructions, users will need read access to
113
99
  documents of `_type=="sanity.assist.task.status"`.
114
-
115
100
  To edit instructions, users will need read and write access to documents of `_type=="sanity.assist.schemaType.annotations"`.
116
-
117
101
  Note that instructions run using the permissions of the user invoking it, so only fields that the user
118
102
  themselves can edit can be changed by the instruction instance.
119
103
 
@@ -125,10 +109,8 @@ that filters out the inspector and actions, based on user properties:
125
109
  ```ts
126
110
  import {CurrentUser, defineConfig} from 'sanity'
127
111
  import {assist} from '@sanity/assist'
128
-
129
112
  export default defineConfig({
130
113
  // ...
131
-
132
114
  plugins: [
133
115
  // ...
134
116
  assist(),
@@ -139,7 +121,6 @@ export default defineConfig({
139
121
  isAiAssistAllowed(currentUser)
140
122
  ? prev
141
123
  : prev.filter((inspector) => inspector.name !== 'ai-assistance'),
142
-
143
124
  unstable_fieldActions: (prev, {currentUser}) =>
144
125
  isAiAssistAllowed(currentUser)
145
126
  ? prev
@@ -148,9 +129,7 @@ export default defineConfig({
148
129
  },
149
130
  ],
150
131
  })
151
-
152
132
  const ALLOWED_ROLES = ['administrator']
153
-
154
133
  function isAiAssistAllowed(user?: CurrentUser | null) {
155
134
  return user && user.roles.some((role) => ALLOWED_ROLES.includes(role.name))
156
135
  }
@@ -164,17 +143,18 @@ assist({
164
143
  assist: {
165
144
  localeSettings: () => Intl.DateTimeFormat().resolvedOptions(),
166
145
  maxPathDepth: 4,
167
- temperature: 0.3
146
+ temperature: 0.3,
147
+ },
148
+ translate: {
149
+ /* see sections about document and field translation */
168
150
  },
169
- translate: { /* see sections about document and field translation */}
170
151
  })
171
152
  ```
172
153
 
173
154
  - `localeSettings`: See section on [date and datetime](#date-and-datetime)
174
155
  - `maxPathDepth`: The max depth for document paths AI Assist will write to.
175
156
  - `temperature`: Influences how much the output of an instruction will vary between runs.
176
-
177
- For more details, please review the TSDocs of the individual config parameters in [assistTypes.ts](./src/assistTypes.ts)
157
+ For more details, please review the TSDocs of the individual config parameters in [assistTypes.ts](./src/assistTypes.ts)
178
158
 
179
159
  ## Schema configuration
180
160
 
@@ -242,25 +222,22 @@ The following types are not supported, and behave as excluded types:
242
222
  - [Image](https://www.sanity.io/docs/image-type) (supported when image has custom fields)
243
223
  - [File](https://www.sanity.io/docs/file-type) (never supported, even when file has custom fields)
244
224
  - [Reference](https://www.sanity.io/docs/reference-type) (supported when configured with embeddingsIndex)
245
-
246
- Fields with these types will not be changed by the assistant, do not have AI Assist actions, and cannot be referenced in instructions.
247
-
248
- Objects where all fields are excluded or unsupported and arrays where all member types are excluded or unsupported
249
- will also be excluded.
225
+ Fields with these types will not be changed by the assistant, do not have AI Assist actions, and cannot be referenced in instructions.
226
+ Objects where all fields are excluded or unsupported and arrays where all member types are excluded or unsupported
227
+ will also be excluded.
250
228
 
251
229
  ### Date and datetime
230
+
252
231
  - [Date](https://www.sanity.io/docs/date-type)
253
232
  - [Datetime](https://www.sanity.io/docs/datetime-type)
254
-
255
- Starting from v3.0.0, AI Assist can write to date and datetime fields. Instructions can use language like "tomorrow at noon" or
256
- "next year", and when Assist writes to the field, it will be converted to a field-compatible value.
257
-
258
- Language about time is locale and timeZone dependant. By default instructions will use the locale and timezone provided
259
- by the browser (`Intl.DateTimeFormat().resolvedOptions()`).
260
-
261
- Alternatively, you can configure the plugin per user with an `assist.localeSettings` function that should return `LocaleSettings`.
233
+ Starting from v3.0.0, AI Assist can write to date and datetime fields. Instructions can use language like "tomorrow at noon" or
234
+ "next year", and when Assist writes to the field, it will be converted to a field-compatible value.
235
+ Language about time is locale and timeZone dependant. By default instructions will use the locale and timezone provided
236
+ by the browser (`Intl.DateTimeFormat().resolvedOptions()`).
237
+ Alternatively, you can configure the plugin per user with an `assist.localeSettings` function that should return `LocaleSettings`.
262
238
 
263
239
  ##### Example
240
+
264
241
  ```ts
265
242
  assist({
266
243
  assist: {
@@ -269,18 +246,19 @@ assist({
269
246
  // forces locale and timeZone for admins
270
247
  return {
271
248
  locale: 'en-US',
272
- timeZone: 'America/New_York'
249
+ timeZone: 'America/New_York',
273
250
  }
274
251
  }
275
252
  // defaultSettings is the same as using:
276
253
  // const {locale, timeZone} = Intl.DateTimeFormat().resolvedOptions()
277
254
  return defaultSettings
278
- }
279
- }
255
+ },
256
+ },
280
257
  })
281
258
  ```
282
259
 
283
- For a list of allowed values for these parameters, see the following resources:
260
+ For a list of allowed values for these parameters, see the following resources:
261
+
284
262
  - `locale`: [Mozilla on Intl](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#getcanonicalocales)
285
263
  - `timeZone`: [Wiki on time zones](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones)
286
264
 
@@ -288,13 +266,10 @@ For a list of allowed values for these parameters, see the following resources:
288
266
 
289
267
  In AI Assist 2.0 and later, conditionally `hidden` and `readOnly` fields can have instructions.
290
268
  These fields can be written to by an instruction, as long as the field is non-hidden and writable when the instruction starts running.
291
-
292
269
  Fields with `hidden` or `readOnly` set to literal `true` will be skipped by AI Assist.
293
-
294
270
  _Note_: An instruction will not re-evaluate these states during a run.
295
271
  I.e., if an instruction makes a change during its execution that triggers another field to change its `hidden` or `readOnly` status,
296
272
  the running instruction will still consider these as if in their original state.
297
-
298
273
  If it is essential that AI Assist _never_ writes to a conditional field,
299
274
  it should be marked with `options.aiAssist.exclude: true`.
300
275
 
@@ -304,22 +279,18 @@ it should be marked with `options.aiAssist.exclude: true`.
304
279
 
305
280
  To enable AI assist for references, first, your project must have an existing [embeddings-index](https://www.sanity.io/docs/embeddings-index-api-overview)
306
281
  that includes the document types it should be able to reference.
307
-
308
282
  You can manage your indexes directly in the studio using the [Embeddings Index Dashboard plugin](https://github.com/sanity-io/embeddings-index-ui#embeddings-index-api-dashboard-for-sanity-studio).
309
283
 
310
284
  #### Set schema options
311
285
 
312
286
  Set `options.aiAssist.embeddingsIndex` for reference fields/types you want to enable reference instructions for.
313
287
  Reference fields with this option set can have instructions attached and will be visited when running instructions for object fields and arrays.
314
-
315
288
  AI Assist will use the embeddings-index, further filtered by the types allowed by the reference, to look up contextually relevant references.
316
289
  For arrays or portable text fields with references, one or more references can be added. Use the instruction text to control this.
317
-
318
290
  Example:
319
291
 
320
292
  ```ts
321
293
  import {defineArrayMember} from 'sanity'
322
-
323
294
  defineField({
324
295
  type: 'reference',
325
296
  name: 'articleReference',
@@ -335,31 +306,24 @@ defineField({
335
306
 
336
307
  An example instruction attached to this field could be:
337
308
  `Given <Document field: Title> suggest a related article`
338
-
339
309
  Running it would use the `article-index` to find a related article based on the current document title.
340
310
 
341
311
  ### Troubleshooting
342
312
 
343
313
  There are limits to how much text the assistant can handle when processing an instruction. Under the hood, AI Assist will add information about your schema, which adds to what's commonly referred to as “the context window.”
344
-
345
314
  If you have a very large schema (that is, many document and field types), it can be necessary to exclude types to limit how much of the context window is used for the schema itself.
346
-
347
315
  We recommend excluding any and all types that aren't likely to benefit from automated workflows. A quick win is typically to exclude array types. It can be a good idea to exclude most non-block types from Portable Text arrays. This will ensure that AI Assist outputs mostly formatted text.
348
-
349
316
  It is also possible to exclude fields/types when creating an instruction. See [Field and type filters](#field-and-type-filters) for more.
350
317
 
351
318
  ## Included document types
352
319
 
353
320
  This plugin adds an `AI Context` document type.
354
-
355
321
  If your Studio uses [Structure Builder](https://www.sanity.io/docs/structure-builder-introduction) to configure the studio structure,
356
322
  you might have to add this document type to your structure.
357
-
358
323
  The document type name can be imported from the plugin:
359
324
 
360
325
  ```ts
361
326
  import {contextDocumentTypeName} from '@sanity/assist'
362
-
363
327
  // put into structure in structure
364
328
  S.documentTypeListItem(contextDocumentTypeName)
365
329
  ```
@@ -368,10 +332,8 @@ S.documentTypeListItem(contextDocumentTypeName)
368
332
 
369
333
  When creating instructions for documents, object fields, array fields, or portable text fields, you can explicitly control what will be visited by AI Assist.
370
334
  By default, the assistant will include all compatible fields and types.
371
-
372
335
  Opting out fields/types per instruction is done using the respective field/type filter checkboxes under the instruction.
373
336
  When using these filters, it is not necessary to tell AI Assist what to include in the instruction text itself.
374
-
375
337
  Note that once the schema targeted by the instruction changes, the following behavior applies:
376
338
 
377
339
  - instructions that include all fields or types will automatically also include the new fields or types
@@ -405,11 +367,10 @@ defineField({
405
367
 
406
368
  This will add a **Generate image description** action to the configured field.
407
369
  The **Generate image description** action will automatically run whenever the image changes.
408
-
409
370
  `imageDescriptionField` can be a nested field, if the image has an object field, i.e. `imageDescriptionField: 'wrapper.altText'`.
410
371
  Fields within array items are not supported.
411
-
412
372
  By default, the caption field will regenerate whenever the image asset changes. To disable this behavior use the following configuration:
373
+
413
374
  ```ts
414
375
  {
415
376
  imageDescriptionField: {
@@ -422,32 +383,20 @@ By default, the caption field will regenerate whenever the image asset changes.
422
383
  ## Image generation
423
384
 
424
385
  <img width="600" alt="image" src="https://github.com/sanity-io/assist/assets/835514/c4de6791-f530-4cd1-b0c2-96ef988bc256">
425
-
426
386
  AI Assist can generate assets for images configured with a prompt field.
427
-
428
387
  An image is generated directly by using the **Generate image from prompt** instruction on the prompt field,
429
388
  or indirectly whenever the image prompt field is written to by an AI Assist instruction.
430
-
431
389
  ### Configure
432
-
433
390
  To enable image generation for an image field, the image must:
434
-
435
391
  - set `options.aiAssist.imageInstructionField` to a child-path relative to the image
436
392
  - have a `string` or `text` field that corresponds to the `imageInstructionField` path
437
-
438
393
  This will add a **Generate image from prompt** instruction to the image prompt field. Running it will generate an image.
439
-
440
394
  Additionally, whenever an AI Assist instruction writes to the image prompt field, the image will be re-generated.
441
-
442
395
  This could be a document instruction, an instruction for the image field or parent object, or directly on the image prompt field.
443
-
444
396
  A common style guide can achieved by adding an instruction to the image prompt field that rewrites its value to include instructions on common style rules.
445
397
  Use AI context documents to apply a reusable style guide to the prompt rewriting as needed.
446
-
447
398
  #### Example
448
-
449
399
  Given the following document schema
450
-
451
400
  ```ts
452
401
  defineType({
453
402
  type: 'document',
@@ -473,20 +422,13 @@ defineType({
473
422
  ],
474
423
  })
475
424
  ```
476
-
477
425
  To directly generate an image based on the value in the prompt field,
478
426
  run the "Generate image from prompt" instruction that is automatically added.
479
-
480
427
  For better image results or to ensure a consistent style, rewrite the prompt before generating the image:
481
-
482
428
  ### Example prompt expansion instruction
483
-
484
429
  <img width="267" alt="image" src="https://github.com/sanity-io/assist/assets/835514/dabc6910-80d3-4a69-940f-49ac5cae9ade">
485
-
486
430
  For better image results, use an instruction that expands the prompt to be more detailed.
487
-
488
431
  Example instruction text:
489
-
490
432
  ```
491
433
  Rewrite image prompts for image generation according to the following rules:
492
434
  - Be Specific: Include detailed descriptions of the scene, objects, colors, and any characters. Instead of saying "a cat in a garden", say "a fluffy gray cat sitting beside pink tulips in a sunny garden".
@@ -496,45 +438,26 @@ Rewrite image prompts for image generation according to the following rules:
496
438
  - Mood and Atmosphere: Describe the mood or atmosphere of the image. Words like 'peaceful', 'dynamic', 'mysterious', or 'joyful' can guide the AI in capturing the right tone.
497
439
  - Avoid Ambiguity: Be clear and direct. Avoid using vague or abstract concepts that the AI might struggle to interpret.
498
440
  - Follow the Guidelines: Ensure your prompt doesn't include any content against usage policies, such as depictions of real people, copyrighted characters, or sensitive subjects.
499
-
500
441
  Keep it 100 words or less.
501
-
502
442
  The prompt to rewrite is:
503
443
  {Reference to image-prompt-field}
504
444
  ```
505
-
506
445
  The rules can be extracted into an AI Context document and reused in other instructions as needed. This approach can also be used to inform a reusable styleguide for image generation.
507
-
508
446
  ## Full document translation
509
-
510
447
  <img width="250" alt="Translate document action" src="https://github.com/sanity-io/assist/assets/835514/932968ee-1a8c-4389-8822-338188f88b40">
511
-
512
448
  AI assist offers full document translations, which is ideal for pairing with [@sanity/document-internationalization](https://github.com/sanity-io/document-internationalization).
513
-
514
449
  Translations are done deeply; visiting nested objects, arrays and even Portable text annotations.
515
-
516
450
  ### What AI Assist full document translations solves
517
-
518
451
  Given a document written in one language, AI assist can translate the document in place to a language specified by a language field in the document.
519
-
520
452
  When the document translation feature is enabled, AI Assist will go through the document field by field, translating all string and portable text fields into the language specified in the document's language field.
521
-
522
453
  This works especially well with [@sanity/document-internationalization](https://github.com/sanity-io/document-internationalization), which uses a strategy of creating copies of the source document for each separate language to be translated into and uses a hidden string field to set the language for each copy.
523
-
524
454
  AI Assist allows editors to translate these documents into the desired language immediately.
525
-
526
455
  ### Configure document translations
527
-
528
456
  To enable full document translations, set `translate.document.languageField` to the path of the language field in your documents.
529
-
530
457
  All documents with a corresponding language field will get a "Translate document" instruction added to the AI Assist drop-down for the document.
531
-
532
458
  To further limit which document types should be enabled for translation instructions, provide an array of document type names to `translate.document.documentTypes`.
533
-
534
459
  If the studio is using [@sanity/document-internationalization](https://github.com/sanity-io/document-internationalization), these options should be the same as those used for that plugin.
535
-
536
460
  **Example configs**
537
-
538
461
  ```ts
539
462
  // This will add a "Translate document" instruction to all documents with a language field
540
463
  assist({
@@ -545,7 +468,6 @@ assist({
545
468
  },
546
469
  })
547
470
  ```
548
-
549
471
  ```ts
550
472
  // This will add a "Translate document" instruction only to the 'article' document type
551
473
  assist({
@@ -557,9 +479,7 @@ assist({
557
479
  },
558
480
  })
559
481
  ```
560
-
561
482
  **All configuration params**
562
-
563
483
  ```ts
564
484
  assist({
565
485
  translate: {
@@ -575,7 +495,6 @@ assist({
575
495
  * this should be the same as `languageField` config for that plugin (which defaults to 'language')
576
496
  */
577
497
  languageField: string,
578
-
579
498
  /**
580
499
  * `documentTypes` should be an array of strings where each entry must match a name from your document schemas.
581
500
  *
@@ -589,29 +508,17 @@ assist({
589
508
  }
590
509
  })
591
510
  ```
592
-
593
511
  ## Field level translations
594
-
595
512
  <img width="250" alt="Translate fields action" src="https://github.com/sanity-io/assist/assets/835514/99819cd4-578e-43b2-8c70-8e39afff5f09">
596
-
597
513
  <img width="250" alt="Translate fields dialog" src="https://github.com/sanity-io/assist/assets/835514/fe3d289c-49b6-46dd-ae2f-cd509a01534a">
598
-
599
514
  AI assist offers field-level translations, which is ideal for use in conjunction with [sanity-plugin-internationalized-array](https://github.com/sanity-io/sanity-plugin-internationalized-array?tab=readme-ov-file#sanity-plugin-internationalized-array) and [@sanity/language-filter](https://github.com/sanity-io/language-filter)
600
-
601
515
  ### What AI Assist field-level translations solves
602
-
603
516
  Given a document with field values in different languages, AI assist can transfer and translate from one language to the others.
604
-
605
517
  The typical use case would be for documents that use internationalized wrapper types to hold values for multiple languages.
606
-
607
518
  AI Assist supports complex values, so language fields that hold nested objects, portable text, or arrays will also be translated.
608
-
609
519
  When initiating translations, editors select a language to translate from and which languages to translate to. This means that AI Assist supports partial translations in cases where editors are responsible for only some languages in the document.
610
-
611
520
  ### Configure field translations
612
-
613
521
  To enable field-level translations, set `translate.field.documentTypes` to an array with which document types should get field translations, and `translate.field.languages`
614
-
615
522
  ```ts
616
523
  assist({
617
524
  translate: {
@@ -625,15 +532,10 @@ assist({
625
532
  },
626
533
  })
627
534
  ```
628
-
629
535
  These documents will get a **Translate fields** instruction added to the document AI Assist dropdown.
630
-
631
536
  Out of the box, this is sufficient config for document types using the `internationalizedArray*` types provided by [sanity-plugin-internationalized-array](https://github.com/sanity-io/sanity-plugin-internationalized-array?tab=readme-ov-file#sanity-plugin-internationalized-array).
632
-
633
537
  It will also work without further config for object types named `locale*`, (e.g. `localeTitle`, `localeDescription`) with one field per language:
634
-
635
538
  _Example locale object supported by default_
636
-
637
539
  ```ts
638
540
  // Object type with name starting with 'locale', and one field per language language
639
541
  defineType({
@@ -654,18 +556,13 @@ defineType({
654
556
  ],
655
557
  })
656
558
  ```
657
-
658
559
  **If your schema is not using either of these structures**, refer to the section on [Custom language fields](#custom-language-fields).
659
-
660
560
  #### Note on document schema depth
661
561
  By default, field level translations will translate 6 "path-segments" deep.
662
-
663
562
  Depth is based on field path segments like so:
664
563
  - `title` has depth 1
665
564
  - `array[_key="no"].title` has depth 3
666
-
667
565
  If this is not sufficient for your document types, use `maxPathDepth`:
668
-
669
566
  ```ts
670
567
  assist({
671
568
  translate: {
@@ -675,14 +572,10 @@ assist({
675
572
  },
676
573
  })
677
574
  ```
678
-
679
575
  Be careful not to set this too high in studios with recursive document schemas, as it could have negative impact on performance.
680
576
  maxPathDepth is hard-capped to 50.
681
-
682
577
  ### Loading field languages
683
-
684
578
  Languages must be an array of objects with an id and title.
685
-
686
579
  ```ts
687
580
  assist({
688
581
  translate: {
@@ -695,9 +588,7 @@ assist({
695
588
  },
696
589
  })
697
590
  ```
698
-
699
591
  Or an asynchronous function that returns an array of objects with an id and title.
700
-
701
592
  ```ts
702
593
  assist({
703
594
  translate: {
@@ -710,9 +601,7 @@ assist({
710
601
  },
711
602
  })
712
603
  ```
713
-
714
604
  The async function contains a configured Sanity client in the first parameter, allowing you to store language options as documents. Your query should return an array of objects with an id and title.
715
-
716
605
  ```ts
717
606
  assist({
718
607
  translate: {
@@ -725,11 +614,8 @@ assist({
725
614
  },
726
615
  })
727
616
  ```
728
-
729
617
  Additionally, you can "pick" fields from a document, to pass into the query. For example, if you have a concept of "Markets" where only certain language fields are required in certain markets.
730
-
731
618
  In this example, each language document has an array of strings called markets to declare where that language can be used. And the document being authored has a single market field.
732
-
733
619
  ```ts
734
620
  assist({
735
621
  translate: {
@@ -748,34 +634,21 @@ assist({
748
634
  },
749
635
  })
750
636
  ```
751
-
752
637
  ### Custom language fields
753
-
754
638
  By providing a function to `translate.field.translationOutputs`, you have complete control over which fields belong to which language.
755
-
756
639
  `translationOutputs` is used when an editor uses the **Translate fields** instruction.
757
-
758
640
  It determines the relationships between document paths: Given a document path and a language, it should return the approriate sibling paths into which translations are output.
759
-
760
641
  `translationOutputs` is invoked once per path in the document (limited to a depth of 6), with the following arguments:
761
-
762
642
  - `documentMember` - the field or array item for a given path; contains the path and its `schemaType`
763
643
  - `enclosingType` - the schema type of the parent holding the member
764
644
  - `translateFromLanguageId` - the `languageId` for the language the users want to translate from
765
645
  - `translateToLanguageIds` - all `languageId`s the user can translate to
766
-
767
646
  The function should return a `TranslationOutput[]` array that contains all the paths where translations from `documentMember` (in the language received in `translateFromLanguageId`) should be output.
768
-
769
647
  The function should return `undefined` for all document members that should not be directly translated, or are nested fields under a translated path.
770
-
771
648
  #### Default function
772
-
773
649
  The default `translationOutputs` is available using `import {defaultTranslationOutputs} from '@sanity/assist`.
774
-
775
650
  #### Example
776
-
777
651
  Given the following document:
778
-
779
652
  ```ts
780
653
  {
781
654
  titles: {
@@ -791,27 +664,19 @@ Given the following document:
791
664
  }
792
665
  }
793
666
  ```
794
-
795
667
  When translating from English to German, `translationOutputs` will be
796
668
  invoked multiple times.
797
-
798
669
  The following parameters will be the same every invocation:
799
-
800
670
  - `translateFromLanguageId` will be `'en'`
801
671
  - `translateToLanguageIds` will be `['de']`
802
-
803
672
  `documentMember` and `enclosingType` will change between each invocation, and take the following values:
804
-
805
673
  1. `{path: 'titles', name: 'titles', schemaType: ObjectSchemaType}`, `ObjectSchemaType`
806
674
  2. `{path: 'titles.en', name: 'en', schemaType: ObjectSchemaType}`, `ObjectSchemaType`
807
675
  3. `{path: 'titles.en.title', name: 'title', schemaType: StringSchemaType}`, `ObjectSchemaType`
808
676
  4. `{path: 'titles.en.subtitle', name: 'subtitle', schemaType: StringSchemaType}`, `ObjectSchemaType`
809
677
  5. `{path: 'titles.de', name: 'de', schemaType: ObjectSchemaType}`, `ObjectSchemaType`
810
-
811
678
  To indicate that you want everything under `title.en` to be translated into `title.de`, `translationOutputs` needs to return `[id: 'de', outputPath: 'titles.de']` when invoked with `documentMember.path: 'titles.en'`.
812
-
813
679
  The following function enables this:
814
-
815
680
  ```ts
816
681
  function translationOutputs(
817
682
  member,
@@ -821,7 +686,6 @@ function translationOutputs(
821
686
  ) {
822
687
  const parentIsLanguageWrapper =
823
688
  enclosingType.jsonType === 'object' && enclosingType.name.startsWith('language')
824
-
825
689
  if (parentIsLanguageWrapper && translateFromLanguageId === member.name) {
826
690
  // [id: 'de', ]
827
691
  return translateToLanguageIds.map((translateToId) => ({
@@ -831,14 +695,11 @@ function translationOutputs(
831
695
  outputPath: [...member.path.slice(0, -1), translateToId],
832
696
  }))
833
697
  }
834
-
835
698
  // ignore other members
836
699
  return undefined
837
700
  }
838
701
  ```
839
-
840
702
  [### Full field translation configuration example]()
841
-
842
703
  ```ts
843
704
  assist({
844
705
  translate: {
@@ -872,26 +733,16 @@ assist({
872
733
  },
873
734
  })
874
735
  ```
875
-
876
736
  ## Adding translation actions to fields
877
-
878
737
  <img width="250" alt="Translate action on field" src="https://github.com/sanity-io/assist/assets/835514/e6dc0860-90a7-4f7a-b3d2-71893b09862f">
879
-
880
738
  <img width="250" alt="Translate fields action on field" src="https://github.com/sanity-io/assist/assets/835514/acc5fa23-2022-4eae-922d-5c83dda7379c">
881
-
882
739
  By default, **Translate document** and **Translate fields…** instructions are only added to the top-level document instruction menu.
883
-
884
740
  These instructions can also be added to fields by setting
885
741
  `options.aiAssist.translateAction: true` for a field or type.
886
-
887
742
  This allows editors to translate only parts of the document and can be useful to enable for `internationalizedArrays` or `locale` wrapper object types.
888
-
889
743
  For document types configured for full document translations, a **Translate** action will be added. Running it will translate the field to the language set in the language field
890
-
891
744
  For document types configured for field translations, a **Translate fields...** action will be added. Running it will open a dialog with language selectors.
892
-
893
745
  #### Example
894
-
895
746
  ```ts
896
747
  defineField({
897
748
  name: 'subtitle',
@@ -904,14 +755,11 @@ defineField({
904
755
  },
905
756
  })
906
757
  ```
907
-
908
758
  ## Translation style guide
909
-
910
759
  In some cases you might want/need the translator to follow a certain style guide - for
911
760
  instance you might tell it not to translate certain words, or be more formal or casual.
912
761
  To configure this you can pass a `styleguide` property under the translation
913
762
  configuration:
914
-
915
763
  ```ts
916
764
  assist({
917
765
  translate: {
@@ -919,21 +767,15 @@ assist({
919
767
  },
920
768
  })
921
769
  ```
922
-
923
770
  The style guide is currently limited to 2000 characters, and the translation might get
924
771
  slower the longer your style guide is. If the provided string is longer than the limit,
925
772
  the plugin will throw upon studio startup.
926
-
927
773
  Note that this is currently only available on a global level - it can not be defined
928
774
  per-field for now.
929
-
930
775
  ### Dynamic styleguide
931
-
932
776
  As of 4.1.0 it is also possible to provide a styleguide async function.
933
777
  The function is passed a context object with Sanity client and the current documentId and schemaType.
934
-
935
778
  Consider caching the results: the function is invoked every time translate runs.
936
-
937
779
  ```ts
938
780
  assist({
939
781
  translate: {
@@ -941,21 +783,15 @@ assist({
941
783
  },
942
784
  })
943
785
  ```
944
-
945
786
  ## Custom field actions
946
-
947
787
  <img width="513" alt="Field action menu with custom actions" src="https://github.com/user-attachments/assets/c613f692-4983-4acc-a8c2-8fb60294682a" />
948
-
949
788
  To incorporate [Agent Actions](https://www.sanity.io/docs/agent-actions?utm_source=github.com&utm_medium=organic_social&utm_campaign=ai-assist&utm_content=)
950
789
  or other custom actions into the AI Assist document and field action menus, use `fieldActions` plugin config.
951
-
952
790
  Because of react hook linting, we recommend defining the `useExampleFieldActions` outside the plugin config:
953
-
954
791
  ```ts
955
792
  //sanity.config.ts
956
793
  import {defineConfig} from 'sanity'
957
794
  import {assist, type AssistFieldActionProps, defineAssistFieldAction} from '@sanity/assist'
958
-
959
795
  function useExampleFieldActions(props: AssistFieldActionProps) {
960
796
  return useMemo(() => [
961
797
  defineAssistFieldAction({
@@ -968,7 +804,6 @@ function useExampleFieldActions(props: AssistFieldActionProps) {
968
804
  },
969
805
  })], [])
970
806
  }
971
-
972
807
  export default defineConfig({
973
808
  //...
974
809
  plugins: [
@@ -982,31 +817,20 @@ export default defineConfig({
982
817
  ]
983
818
  })
984
819
  ```
985
-
986
820
  ### `useExampleFieldActions`
987
-
988
821
  `useExampleFieldActions` is called for the document itself and for all fields within it. It can call React hooks.
989
822
  Actions returned by the hook will be added to the corresponding document or field menu.
990
-
991
823
  It is recommended to wrap the returned actions in `useMemo`. The returned array can contain `undefined` values.
992
824
  These will be filtered out.
993
-
994
-
995
825
  See TSDocs for [AssistFieldActionProps](./src/fieldActions/customFieldActions.tsx) for details on how each
996
826
  prop can be used to parameterize Agent Actions on sanity client.
997
-
998
827
  #### Agent Action examples
999
-
1000
828
  Below are some examples of agent action integration.
1001
829
  For more, see [HOW-TO-USE](../studio/examples/agentActions/HOW-TO-USE.md)
1002
-
1003
830
  ##### Fix spelling
1004
-
1005
831
  The following example adds a "Fix spelling" action to all fields and the document itself.
1006
-
1007
832
  It will fix spelling mistakes for the field it is invoked for (and all child fields, for arrays and objects),
1008
833
  by calling `client.agent.action.transform`.
1009
-
1010
834
  ```ts
1011
835
  function useExampleFieldActions(props: AssistFieldActionProps) {
1012
836
  const {
@@ -1047,17 +871,13 @@ function useExampleFieldActions(props: AssistFieldActionProps) {
1047
871
  ])
1048
872
  }
1049
873
  ```
1050
-
1051
874
  ##### Fill field (contextually aware)
1052
-
1053
875
  The following example adds a "Fill field" action to all fields in the document by calling `client.agent.action.generate`.
1054
-
1055
876
  The action will:
1056
877
  - create the document as a draft if it does not exist, respecting initial values (`targetDocument`)
1057
878
  - use existing document state to determine what should be put in the the field (`instruction`, `instructionParams`)
1058
879
  - pass the current readOnly and hidden state currently use by the document form to the Agent Action, so it respects it (`conditionalPaths`)
1059
880
  - output to the field the action started from (`target.path`)
1060
-
1061
881
  ```ts
1062
882
  function useExampleFieldActions(props: AssistFieldActionProps) {
1063
883
  const {
@@ -1070,16 +890,13 @@ function useExampleFieldActions(props: AssistFieldActionProps) {
1070
890
  path,
1071
891
  schemaType,
1072
892
  } = props
1073
-
1074
893
  // hook usage has to happen outside onAction, so preassemble state in useExampleFieldActions and pass to useMemo
1075
894
  const client = useClient({apiVersion: 'vX'})
1076
-
1077
895
  return useMemo(() => {
1078
896
  if (actionType === 'document') {
1079
897
  // in this case we dont want a document action
1080
898
  return []
1081
899
  }
1082
-
1083
900
  return [
1084
901
  defineAssistFieldAction({
1085
902
  title: 'Fill field',
@@ -1136,15 +953,10 @@ function useExampleFieldActions(props: AssistFieldActionProps) {
1136
953
  ])
1137
954
  }
1138
955
  ```
1139
-
1140
956
  ### Define helpers
1141
-
1142
957
  #### `defineAssistFieldAction`
1143
-
1144
958
  Adds a single action that will appear in the document/field action menu.
1145
-
1146
959
  `onAction` _cannot_ call hooks. If state from hook is needed, it should be pre-assembled by `useExampleFieldActions`
1147
-
1148
960
  ```ts
1149
961
  defineAssistFieldAction({
1150
962
  title: 'Do something',
@@ -1154,13 +966,10 @@ defineAssistFieldAction({
1154
966
  },
1155
967
  })
1156
968
  ```
1157
-
1158
969
  #### `defineAssistFieldActionGroup`
1159
-
1160
970
  Adds a group to hold one or more actions (or nested groups).
1161
971
  `children` can contain `undefined` values. These will be filtered out.
1162
972
  A group that has an empty `children` array (or only undefined values) will be filtered out.
1163
-
1164
973
  By default, any actions returned by `useExampleFieldActions` will be grouped under `title`.
1165
974
  ```ts
1166
975
  function useExampleFieldActions(props: AssistFieldActionProps) {
@@ -1175,13 +984,10 @@ function useExampleFieldActions(props: AssistFieldActionProps) {
1175
984
  ]
1176
985
  }
1177
986
  ```
1178
-
1179
987
  #### Only groups in `useExampleFieldActions`
1180
988
  If `useExampleFieldActions` _only_ returns groups, the default wrapper group will be omitted. This allows full control over each group title.
1181
-
1182
989
  #### `defineFieldActionDivider`
1183
990
  Adds a divider between actions or groups. Takes no arguments:
1184
-
1185
991
  ```ts
1186
992
  function useExampleFieldActions(props: AssistFieldActionProps) {
1187
993
  return useMemo(() => [
@@ -1191,25 +997,16 @@ function useExampleFieldActions(props: AssistFieldActionProps) {
1191
997
  ], [])
1192
998
  }
1193
999
  ```
1194
-
1195
1000
  ### `useUserInput`
1196
-
1197
1001
  <img width="522" alt="user input dialog" src="https://github.com/user-attachments/assets/86966468-9a28-4c0b-99f3-e4b80fdbe691" />
1198
-
1199
1002
  For certain actions, it is useful to have the user provide additional information or details that can be used
1200
1003
  as parameters for the action.
1201
-
1202
1004
  `useUserInput` returns a `getUserInput` function that can be called and awaited to return input from the user.
1203
-
1204
1005
  The `getUserInput` function takes input configuration and will display an input dialog to the user.
1205
1006
  When the user completes the dialog, the user inputted text will be available (or undefined if the user closed the dialog).
1206
-
1207
-
1208
1007
  ```ts
1209
-
1210
1008
  function useExampleFieldActions(props: AssistFieldActionProps) {
1211
1009
  const getUserInput = useUserInput()
1212
-
1213
1010
  return useMemo(
1214
1011
  () => [
1215
1012
  defineAssistFieldAction({
@@ -1232,7 +1029,6 @@ function useExampleFieldActions(props: AssistFieldActionProps) {
1232
1029
  if (!inputResult) {
1233
1030
  return // user closed the dialog
1234
1031
  }
1235
-
1236
1032
  //use the result from each input
1237
1033
  //const [{result: topic}, {result: facts}] = inputResult
1238
1034
  },
@@ -1242,35 +1038,13 @@ function useExampleFieldActions(props: AssistFieldActionProps) {
1242
1038
  )
1243
1039
  }
1244
1040
  ```
1245
-
1246
1041
  ## Caveats
1247
-
1248
1042
  Large Language Models (LLMs) are a new technology. Constraints and limitations are still being explored,
1249
1043
  but some common caveats to the field that you may run into using AI Assist are:
1250
-
1251
1044
  - Limits to instruction length: Long instructions on deep content structures may exhaust model context
1252
1045
  - Timeouts: To be able to write structured content, we're using the largest language models - long-running results may time out or intermittently fail
1253
1046
  - Limited capacity: The underlying LLM APIs used by AI Assist are resource-constrained
1254
-
1255
1047
  ## Third party sub-processors
1256
-
1257
1048
  This version of the feature uses OpenAI.com as a third-party sub-processor. Their security posture has been vetted by Sanity's security team, and approved for use.
1258
-
1259
1049
  ## License
1260
-
1261
1050
  [MIT](LICENSE) © Sanity
1262
-
1263
- ## Develop & test
1264
-
1265
- This plugin uses [@sanity/plugin-kit](https://github.com/sanity-io/plugin-kit)
1266
- with default configuration for build & watch scripts.
1267
-
1268
- See [Testing a plugin in Sanity Studio](https://github.com/sanity-io/plugin-kit#testing-a-plugin-in-sanity-studio)
1269
- on how to run this plugin with hotreload in the studio.
1270
-
1271
- ### Release new version
1272
-
1273
- Run ["CI & Release" workflow](https://github.com/sanity-io/assist/actions/workflows/main.yml).
1274
- Make sure to select the main branch and check "Release new version".
1275
-
1276
- Semantic release will only release on configured branches, so it is safe to run release on any branch.