@sanity/assist 1.2.13 → 1.2.15-lang.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.
Files changed (36) hide show
  1. package/README.md +392 -6
  2. package/dist/index.d.ts +170 -3
  3. package/dist/index.esm.js +1986 -111
  4. package/dist/index.esm.js.map +1 -1
  5. package/dist/index.js +1980 -105
  6. package/dist/index.js.map +1 -1
  7. package/package.json +15 -14
  8. package/src/_lib/form/DocumentForm.tsx +1 -1
  9. package/src/assistDocument/components/instruction/InstructionInput.tsx +5 -4
  10. package/src/assistDocument/components/instruction/InstructionOutputField.tsx +45 -0
  11. package/src/assistDocument/components/instruction/InstructionOutputInput.tsx +205 -0
  12. package/src/assistDocument/hooks/useStudioAssistDocument.ts +5 -32
  13. package/src/assistFormComponents/AssistField.tsx +5 -4
  14. package/src/assistFormComponents/AssistFormBlock.tsx +2 -3
  15. package/src/assistFormComponents/validation/listItem.tsx +2 -2
  16. package/src/assistInspector/FieldAutocomplete.tsx +1 -0
  17. package/src/assistInspector/InstructionTaskHistoryButton.tsx +2 -3
  18. package/src/assistInspector/helpers.ts +7 -9
  19. package/src/assistLayout/AssistLayout.tsx +9 -6
  20. package/src/fieldActions/assistFieldActions.tsx +14 -8
  21. package/src/fieldActions/translateActions.tsx +118 -0
  22. package/src/helpers/assistSupported.ts +1 -1
  23. package/src/node_modules/.vitest/results.json +1 -0
  24. package/src/plugin.tsx +12 -2
  25. package/src/presence/AssistAvatar.tsx +1 -1
  26. package/src/schemas/assistDocumentSchema.tsx +39 -0
  27. package/src/schemas/serialize/serializeSchema.test.ts +15 -2
  28. package/src/schemas/serialize/serializeSchema.ts +8 -7
  29. package/src/schemas/typeDefExtensions.ts +12 -1
  30. package/src/translate/FieldTranslationProvider.tsx +254 -0
  31. package/src/translate/getLanguageParams.ts +26 -0
  32. package/src/translate/paths.test.ts +87 -0
  33. package/src/translate/paths.ts +151 -0
  34. package/src/translate/types.ts +159 -0
  35. package/src/types.ts +21 -2
  36. package/src/useApiClient.ts +63 -0
package/README.md CHANGED
@@ -16,8 +16,14 @@
16
16
  - [Disable for a field](#disable-for-a-field)
17
17
  - [Disable for an array type](#disable-for-an-array-type)
18
18
  - [Unsupported types](#unsupported-types)
19
+ - [Reference support](#reference-support)
19
20
  - [Troubleshooting](#troubleshooting)
20
21
  - [Included document types](#included-document-types)
22
+ - [Field and type filters](#field-and-type-filters)
23
+ - [Caption generation](#caption-generation)
24
+ - [Full document translation](#full-document-translation)
25
+ - [What it solves](#what-ai-assist-full-document-translations-solves)
26
+ - [Configure](#configure-document-translations)
21
27
  - [License](#license)
22
28
  - [Develop \& test](#develop--test)
23
29
  - [Release new version](#release-new-version)
@@ -167,13 +173,13 @@ defineType({
167
173
 
168
174
  The following types are not supported, and behave as excluded types:
169
175
  * [Number](https://www.sanity.io/docs/number-type)
170
- * [Reference](https://www.sanity.io/docs/reference-type)
171
176
  * [Slug](https://www.sanity.io/docs/slug-type)
172
177
  * [Url](https://www.sanity.io/docs/url-type)
173
178
  * [Date](https://www.sanity.io/docs/date-type)
174
179
  * [Datetime](https://www.sanity.io/docs/datetime-type)
175
180
  * [Image](https://www.sanity.io/docs/image-type) (supported when image has custom fields)
176
181
  * [File](https://www.sanity.io/docs/file-type) (never supported, even when file has custom fields)
182
+ * [Reference](https://www.sanity.io/docs/reference-type) (supported when configured with embeddingsIndex)
177
183
 
178
184
  Types and fields with `hidden` or `readonly` with a truthy value (`true` or `function`) are not supported.
179
185
  (Hidden and readOnly fields can be referenced in instructions still)
@@ -183,6 +189,44 @@ Fields with these types will not be changed by the assistant, do not have AI Ass
183
189
  Objects where all fields are excluded or unsupported and arrays where all member types are excluded or unsupported
184
190
  will also be excluded.
185
191
 
192
+ ### Reference support
193
+
194
+ #### Create an Embeddings-index
195
+ To enable AI assist for references, first, your project must have an existing [embeddings-index](https://www.sanity.io/docs/embeddings-index-api-overview)
196
+ with the documents it should be able to reference.
197
+
198
+ 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).
199
+
200
+ #### Set schema options
201
+ Set `options.aiWritingAssistance.embeddingsIndex` for reference fields/types you want to enable reference instructions for.
202
+ Reference fields with this options set can have instructions attached to them, and will be visited when running instructions for object fields and arrays.
203
+
204
+ AI assist will use the embeddings-index, filtered by the types allowed by the reference to look up contextually relevant references.
205
+ For arrays or portable text fields with references, one more references can be added. Use the instruction text to control this.
206
+
207
+ Example:
208
+
209
+ ```ts
210
+ import {defineArrayMember} from 'sanity'
211
+
212
+ defineField({
213
+ type: 'reference',
214
+ name: 'articleReference',
215
+ title: 'Article referene',
216
+ to: [ { type: 'article'} ],
217
+ options: {
218
+ aiWritingAssistance: {
219
+ embeddingsIndex: 'article-index'
220
+ },
221
+ },
222
+ })
223
+ ```
224
+
225
+ An example instruction attached to this field could be:
226
+ `Given <Document field: Title> suggest a related article`
227
+
228
+ Running it would use the `article-index` to find an related article based on the current document title.
229
+
186
230
  ### Troubleshooting
187
231
 
188
232
  There are limits to how much text the AI can process when processing an instruction. Under the hood, the AI Assist will add information about your schema, which adds to what's commonly referred to as “the context window.”
@@ -191,6 +235,8 @@ If you have a very large schema (that is, many document and field types), it can
191
235
 
192
236
  We recommend excluding any and all types which rarely would 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 the Sanity Assist outputs mostly formatted text.
193
237
 
238
+ It is also possible to exclude fields/types when creating an instruction. See [Field and type filters](#field-and-type-filters) for more.
239
+
194
240
  ## Included document types
195
241
 
196
242
  This plugin adds an `AI Context` document type.
@@ -206,6 +252,351 @@ import {contextDocumentTypeName} from '@sanity/assist'
206
252
  S.documentTypeListItem(contextDocumentTypeName)
207
253
  ```
208
254
 
255
+ ## Field and type filters
256
+
257
+ When creating instructions for a document, objects fields, array fields or portable text fields, you can explicitly control what will be visited by AI Assist.
258
+ By default, all fields and types configured for assist will be included.
259
+
260
+ Opting out fields/types per instruction is done using the respective field/type filter checkboxes under the instruction.
261
+ When using these filters, it is not necessary to tell Assist what to include in the instruction text itself.
262
+
263
+ Note that if the schema targeted by the instruction changes, the following behavior applies:
264
+ * instructions that included all fields or types will automatically also include the new fields or types
265
+ * instructions that have excluded one or more fields or types, will NOT include the new fields or types
266
+
267
+ ## Caption generation
268
+ AI Assist can optionally generate captions for images. This has to be enabled on an image-type/field,
269
+ by setting the `options.captionField` on the image type, where `captionField` is the field name of a
270
+ custom string-field on the image object:
271
+
272
+ ## Full document translation
273
+ AI assist offers full document translations, which is ideal for pairing with [@sanity/document-internationalization](https://github.com/sanity-io/document-internationalization).
274
+
275
+ ### What AI Assist full document translations solves
276
+
277
+ 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.
278
+
279
+ 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.
280
+
281
+ This works well with [@sanity/document-internationalization](https://github.com/sanity-io/document-internationalization), where documents are duplicated from a source language and set a hidden language field.
282
+
283
+ AI assist allows editors to translate these documents into the desired language immediately.
284
+
285
+ ### Configure document translations
286
+
287
+ To enable full document translations, set `translate.document.languageField` to the path of the language field in your documents.
288
+
289
+ All documents with a language field will get a "Translate document" instruction added to the assist drop-down for the document.
290
+
291
+ To limit which document types get "Translate document" further, provide `translate.document.documentTypes` with an array of document type names.
292
+
293
+ 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.
294
+
295
+ **Example configs**
296
+
297
+ ```ts
298
+ // This will add a "Translate document" instruction to all documents with a language field
299
+ assist({
300
+ translate: {
301
+ document: {
302
+ languageField: 'language'
303
+ }
304
+ }
305
+ })
306
+ ```
307
+
308
+ ```ts
309
+ // This will add a "Translate document" instruction only to the 'article' document type
310
+ assist({
311
+ translate: {
312
+ document: {
313
+ languageField: 'language',
314
+ documentTypes: ['article']
315
+ }
316
+ }
317
+ })
318
+ ```
319
+
320
+ **All configuration params**
321
+ ```ts
322
+ assist({
323
+ translate: {
324
+ /** Config for document types with a single language field that determines the language for the whole document. */
325
+ document: {
326
+ /**
327
+ * Required config, enable document tranlations.
328
+ *
329
+ * Path to language field in documents. Can be a hidden field.
330
+ * For instance: 'config.language'
331
+ *
332
+ * For projects that use the `@sanity/document-internationalization` plugin,
333
+ * this should be the same as `languageField` config for that plugin (which defaults to 'language')
334
+ */
335
+ languageField: string,
336
+
337
+ /**
338
+ * `documentTypes` should be an array of strings where each entry must match a name from your document schemas.
339
+ *
340
+ * this property will add a translate instruction to these document types if defined.
341
+ * If undefined, the instruction will be added to all documents with aiAssistance enabled and a field matching `languageField` config.
342
+ *
343
+ * Documents with translation support will get a "Translate document>" instruction added.
344
+ **/
345
+ documentTypes: string[]
346
+ }
347
+ }
348
+ })
349
+ ```
350
+
351
+ ## Field level translations
352
+
353
+ AI assist offers field-level translations, which is ideal for using alongside 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]
354
+
355
+ ### What AI Assist field-level translations solves
356
+
357
+ Given a document with field values in different languages, AI assist can transfer and translate from one language to the others.
358
+
359
+ The typical use case would be for documents that use internationalized wrapper types to hold values for multiple languages.
360
+
361
+ AI Assist supports complex values, so language fields that hold nested objects, portable text, or arrays will also be translated.
362
+
363
+ 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.
364
+
365
+ ### Configure field translations
366
+ To enable field-level translations, set `translate.field.documentTypes` to an array with which document types should get field translations, and `translate.field.languages`
367
+
368
+ ```ts
369
+ assist({
370
+ translate: {
371
+ field: {
372
+ documentTypes: ['article'],
373
+ languages: [
374
+ {id: 'en', title: 'English'},
375
+ {id: 'de', title: 'German'}
376
+ ]
377
+ },
378
+ },
379
+ })
380
+ ```
381
+
382
+ These documents will get a "Translate fields" instruction added to the document AI Assist dropdown.
383
+
384
+ Out of the box, this is sufficient config for document types using `internationalizedArray*` types for localization [sanity-plugin-internationalized-array](https://github.com/sanity-io/sanity-plugin-internationalized-array?tab=readme-ov-file#sanity-plugin-internationalized-array).
385
+
386
+ It will also work without further config for object types named "locale*", with one field per language:
387
+
388
+ *Example locale object supported by default*
389
+
390
+ ```ts
391
+ // Object type with name starting with 'locale', and one field per language language
392
+ defineType({
393
+ type: 'object',
394
+ name: 'localeString',
395
+ fields: [
396
+ defineField({
397
+ // these do not have to be string, could be any type
398
+ type: 'string',
399
+ name: 'en',
400
+ title: 'English'
401
+ }),
402
+ defineField({
403
+ type: 'string',
404
+ name: 'de',
405
+ title: 'German'
406
+ })
407
+ ]
408
+ })
409
+ ```
410
+
411
+ **If your schema is not using either of these structures**, confer [Custom language fields](#custom-language-fields).
412
+
413
+ ### Loading field languages
414
+ Languages must be an array of objects with an id and title.
415
+
416
+ ```ts
417
+ assist({
418
+ translate: {
419
+ field: {
420
+ languages: [
421
+ {id: 'en', title: 'English'},
422
+ {id: 'de', title: 'German'}
423
+ ]
424
+ },
425
+ },
426
+ })
427
+ ```
428
+
429
+ Or an asynchronous function that returns an array of objects with an id and title.
430
+
431
+ ```ts
432
+ assist({
433
+ translate: {
434
+ field: {
435
+ languages: async () => {
436
+ const response = await fetch('https://example.com/languages')
437
+ return response.json()
438
+ }
439
+ },
440
+ },
441
+ })
442
+ ```
443
+
444
+ 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.
445
+
446
+
447
+ ```ts
448
+ assist({
449
+ translate: {
450
+ field: {
451
+ languages: async () => {
452
+ const response = await client.fetch(`*[_type == "language"]{ id, title }`)
453
+ return response
454
+ }
455
+ },
456
+ },
457
+ })
458
+ ```
459
+
460
+ 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.
461
+
462
+ 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.
463
+
464
+ ```ts
465
+ assist({
466
+ translate: {
467
+ field: {
468
+ selectLanguageParams: {
469
+ market: 'market'
470
+ },
471
+ languages: async (client, {market = ``}) => {
472
+ const response = await client.fetch(
473
+ `*[_type == "language" && $market in markets]{ id, title }`,
474
+ {market}
475
+ )
476
+ return response
477
+ },
478
+ },
479
+ },
480
+ })
481
+ ```
482
+
483
+ ### Custom language fields
484
+ By providing a function to `translate.field.translationOutputs`, complete control over which fields belong to which language is given.
485
+
486
+ `translationOutputs` is used when an editor uses the "Translate fields" instruction.
487
+
488
+ It determines the relationships between document paths: Given a document path and a language, it should return into which sibling paths translations are output.
489
+
490
+ `translationOutputs` is invoked once per path in the document (limited to a depth of 6), with the following:
491
+
492
+ * `documentMember` - the field or array item for a given path; contains the path and its schemaType,
493
+ * `enclosingType` - the schema type of the parent holding the member
494
+ * `translateFromLanguageId` - the languageId for the language the users want to to translate from
495
+ * `translateToLanguageIds` - all languageIds the user can translate to
496
+
497
+ The function should return a `TranslationOutput[]` array that contains all the paths where translations from `documentMember` (in the language given by translateFromLanguageId) should be output.
498
+
499
+ The function should return `undefined` for all documentMembers that should not be directly translated, or are nested fields under a translated path.
500
+
501
+ #### Default function
502
+
503
+ The default `translationOutputs` is available using `import {defaultTranslationOutputs} from '@sanity/assist`.
504
+
505
+ #### Example
506
+
507
+ Given the following document:
508
+
509
+ ```ts
510
+ {
511
+ titles: {
512
+ _type: 'languageObject',
513
+ en: {
514
+ _type: 'titleObject',
515
+ title: 'Some title',
516
+ subtitle: 'Some subtitle'
517
+ },
518
+ de: {
519
+ _type: 'titleObject',
520
+ }
521
+ }
522
+ }
523
+ ```
524
+
525
+ When translating from English to German, `translationOutputs` will be
526
+ invoked multiple times.
527
+
528
+ The following parameters will be the same every invocation:
529
+
530
+ * `translateFromLanguageId` will be `'en'`
531
+ * `translateToLanguageIds` will be `['de']`
532
+
533
+ `documentMember` and `enclosingType` will change between each invocation, and take the following values:
534
+
535
+ 1. `{path: 'titles', name: 'titles', schemaType: ObjectSchemaType}`, `ObjectSchemaType`
536
+ 2. `{path: 'titles.en', name: 'en', schemaType: ObjectSchemaType}`, `ObjectSchemaType`
537
+ 3. `{path: 'titles.en.title', name: 'title', schemaType: StringSchemaType}`, `ObjectSchemaType`
538
+ 4. `{path: 'titles.en.subtitle', name: 'subtitle', schemaType: StringSchemaType}`, `ObjectSchemaType`
539
+ 5. `{path: 'titles.de', name: 'de', schemaType: ObjectSchemaType}`, `ObjectSchemaType`
540
+
541
+ 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'`.
542
+
543
+ The following function enables this:
544
+
545
+ ```ts
546
+ function translationOutputs(member, enclosingType, translateFromLanguageId, translateToLanguageIds) {
547
+ const parentIsLanguageWrapper = enclosingType.jsonType === 'object' && enclosingType.name.startsWith('language')
548
+
549
+ if (parentIsLanguageWrapper && translateFromLanguageId === member.name) {
550
+
551
+ // [id: 'de', ]
552
+ return translateToLanguageIds.map((translateToId) => ({
553
+ id: translateToId,
554
+ // in this example, member.path is 'titles.en'
555
+ // so this changes titles.en -> titles.de
556
+ outputPath: [...member.path.slice(0, -1), translateToId],
557
+ }))
558
+ }
559
+
560
+ // ignore other members
561
+ return undefined
562
+ }
563
+ ```
564
+
565
+ ### Full field translation configuration example
566
+
567
+ ```ts
568
+ assist({
569
+ translate: {
570
+ field: {
571
+ documentTypes: ['article'],
572
+ selectLanguageParams: {market: 'market'},
573
+ apiVersion: '2023-01-01',
574
+ languages: (client, {market}) => {
575
+ return client.fetch(
576
+ `*[_type == "language" && $market in markets]{ id, title }`,
577
+ {market}
578
+ )
579
+ },
580
+ translationOutputs: (member, enclosingType, fromLanguageId, toLanguageIds) => {
581
+ // When the document member is named the same as fromLangagueId
582
+ // and it is a field in a object with a name starting with "language"
583
+ // then we return the paths to all other sibling language fields (and their langauge id)
584
+ // It is ok that the member is an object, then all child fields will be translated
585
+ if (translateFromLanguageId === member.name && enclosingType.jsonType === 'object' && enclosingType.name.startsWith('locale')) {
586
+ return translateToLanguageIds.map((translateToId) => ({
587
+ id: translateToId,
588
+ //changes path.to.en -> path.to.de (for instance)
589
+ outputPath: [...member.path.slice(0, -1), translateToId],
590
+ }))
591
+ }
592
+ // all other member paths are skipped
593
+ return undefined
594
+ }
595
+ },
596
+ },
597
+ })
598
+ ```
599
+
209
600
  ## Caveats
210
601
 
211
602
  Large Language Models (LLMs) are a new technology. Constraints and limitations are still being explored,
@@ -215,12 +606,7 @@ but some common caveats to the field that you may run into using AI Assist are:
215
606
  * Timeouts: To be able to write structured content, we're using the largest language models - long-running results may time out or intermittently fail
216
607
  * Limited capacity: The underlying LLM APIs used by AI Assist are resource constrained
217
608
 
218
- ## Other features
219
609
 
220
- ### Caption generation
221
- AI Assist can optionally generate captions for images. This has to be enabled on an image-type/field,
222
- by setting the `options.captionField` on the image type, where `captionField` is the field name of a
223
- custom string-field on the image object:
224
610
 
225
611
  ```tsx
226
612
  defineField({
package/dist/index.d.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  import {JSX as JSX_2} from 'react/jsx-runtime'
2
+ import {Path} from 'sanity'
2
3
  import {Plugin as Plugin_2} from 'sanity'
3
- import {SanityClient} from '@sanity/client'
4
+ import {SanityClient} from 'sanity'
5
+ import {SanityClient as SanityClient_2} from '@sanity/client'
6
+ import {SchemaType} from 'sanity'
4
7
 
5
8
  export declare const assist: Plugin_2<void | AssistPluginConfig>
6
9
 
@@ -12,6 +15,7 @@ export declare interface AssistOptions {
12
15
  }
13
16
 
14
17
  declare interface AssistPluginConfig {
18
+ translate?: TranslationConfig
15
19
  /**
16
20
  * Set this to false to disable model migration from the alpha version of this plugin
17
21
  */
@@ -19,13 +23,166 @@ declare interface AssistPluginConfig {
19
23
  /**
20
24
  * @internal
21
25
  */
22
- __customApiClient?: (defaultClient: SanityClient) => SanityClient
26
+ __customApiClient?: (defaultClient: SanityClient_2) => SanityClient_2
23
27
  }
24
28
 
25
29
  export declare const contextDocumentTypeName: 'assist.instruction.context'
26
30
 
31
+ declare interface DocumentMember {
32
+ schemaType: SchemaType
33
+ path: Path
34
+ name: string
35
+ }
36
+
37
+ declare interface DocumentTranslationConfig {
38
+ /**
39
+ * Path to language field in documents. Can be a hidden field.
40
+ * For instance: 'config.language'
41
+ *
42
+ * For projects that use the `@sanity/document-internationalization` plugin,
43
+ * this should be the same as `languageField` config for that plugin.
44
+ *
45
+ * Default: 'language'
46
+ */
47
+ languageField: string
48
+ /**
49
+ * `documentTypes` should be an array of strings where each entry must match a name from your document schemas.
50
+ *
51
+ * If defined, this property will add a translate instruction to these document types.
52
+ * If undefined, the instruction will be added to all documents with aiAssistance enabled and a field matching `documentLanguageField` config.
53
+ *
54
+ * Documents with translation support will get a "Translate document>" instruction added.
55
+ **/
56
+ documentTypes?: string[]
57
+ }
58
+
59
+ declare interface FieldTranslationConfig {
60
+ /**
61
+ * `documentTypes` should be an array of strings where each entry must match a name from your document schemas.
62
+ *
63
+ * If defined, matching document will get a "Translate fields" instruction added.
64
+ **/
65
+ documentTypes?: string[]
66
+ /**
67
+ *
68
+ * Used for display strings in the Studio, and to determine languages for field level translations
69
+ *
70
+ * If the studio is using the sanity-plugin-internationalized-array plugin, this
71
+ * should be set to the same configuration.
72
+ */
73
+ languages: Language[] | LanguageCallback
74
+ /**
75
+ * API version for client passed to LanguageCallback for languages
76
+ * https://www.sanity.io/docs/api-versioning
77
+ * @defaultValue '2022-11-27'
78
+ */
79
+ apiVersion?: string
80
+ /**
81
+ * Specify fields that should be available in the languages callback:
82
+ * ```tsx
83
+ * {
84
+ * select: {
85
+ * markets: 'markets'
86
+ * },
87
+ * languages: (client, {markets}) =>
88
+ * client.fetch('*[_type == "language" && market in $markets]{id,title}', {markets})
89
+ * }
90
+ * ```
91
+ *
92
+ * If the studio is using the sanity-plugin-internationalized-array plugin, this
93
+ * should be set to the same configuration.
94
+ */
95
+ selectLanguageParams?: Record<string, string>
96
+ /**
97
+ * `translationOutputs` is used when the "Translate fields" instruction is started by a Studio user.
98
+ *
99
+ * It determines the relationships between document paths: Given a document path and a language, into which
100
+ * sibling paths should translations be output.
101
+
102
+ *
103
+ * `translationOutputs` is invoked once per path in the document (limited to a depth of 6), with the following:
104
+ *
105
+ * * `documentMember` - the field or array item for a given path; contains the path and its schemaType,
106
+ * * `enclosingType` - the schema type of parent holding the member
107
+ * * `translateFromLanguageId` - the languageId for the language the user want to translate from
108
+ * * `translateToLanguageIds` - all languageIds the user can translate to
109
+ *
110
+ * The function should return a `TranslationOutput[]` array that contains all the paths where translations from
111
+ * documentMember language (translateFromLanguageId) should be output.
112
+ *
113
+ * The function should return `undefined` for all documentMembers that should not be directly translated,
114
+ * or are nested fields under a translated path.
115
+ *
116
+ * ## Default function
117
+ *
118
+ * The default function for `translationOutputs` is configured to be automatically compatible with sanity-plugin-internationalized-array
119
+ * and object types prefixed with "locale".
120
+ *
121
+ * See <link to source for defaultTranslationOutputs> implementation details.
122
+ *
123
+ * ## Example
124
+ * A document has the following document members:
125
+ * * `{path: 'localeObject.en', schemaType: ObjectSchemaType}`
126
+ * * `{path: 'localeObject.en.title', schemaType: StringSchemaType}`
127
+ * * `{path: 'localeObject.de', schemaType: ObjectSchemaType}`,
128
+ * * `{path: 'localeObject.de.title', schemaType: StringSchemaType}`
129
+ *
130
+ * `translationOutputs` for invoked with `translateFromLanguageId` `en`,
131
+ * should only return [{id: 'de', outputPath: 'localeObject.de'}] for the `'localeObject.en'` path,
132
+ * and undefined for all the other members.
133
+ *
134
+ * ### Example implementation
135
+ * ```ts
136
+ * function translationOutputs(member, enclosingType, translateFromLanguageId, translateToLanguageIds)
137
+ * if (enclosingType.jsonType === 'object' && enclosingType.name.startsWith('locale') && translateFromLanguageId === member.name) {
138
+ * return translateToLanguageIds.map((translateToId) => ({
139
+ * id: translateToId,
140
+ * outputPath: [...member.path.slice(0, -1), translateToId],
141
+ * }))
142
+ * }
143
+ * return undefined
144
+ * }
145
+ * ```
146
+ **/
147
+ translationOutputs?: TranslationOutputsFunction
148
+ }
149
+
150
+ declare interface Language {
151
+ id: string
152
+ title?: string
153
+ }
154
+
155
+ declare type LanguageCallback = (
156
+ client: SanityClient,
157
+ selectedLanguageParams: Record<string, unknown>,
158
+ ) => Promise<Language[]>
159
+
27
160
  export declare function SchemaTypeTool(): JSX_2.Element
28
161
 
162
+ declare interface TranslationConfig {
163
+ /**
164
+ * Config for document types with fields in multiple languages in the same document.
165
+ */
166
+ field?: FieldTranslationConfig
167
+ /**
168
+ * Config for document types with a single language field that determines the language for the whole document.
169
+ */
170
+ document?: DocumentTranslationConfig
171
+ }
172
+
173
+ declare interface TranslationOutput {
174
+ /** Language id */
175
+ id: string
176
+ outputPath: Path
177
+ }
178
+
179
+ declare type TranslationOutputsFunction = (
180
+ documentMember: DocumentMember,
181
+ enclosingType: SchemaType,
182
+ translateFromLanguageId: string,
183
+ translateToLanguageIds: string[],
184
+ ) => TranslationOutput[] | undefined
185
+
29
186
  export {}
30
187
 
31
188
  declare module 'sanity' {
@@ -44,7 +201,17 @@ declare module 'sanity' {
44
201
  }
45
202
  interface NumberOptions extends AssistOptions {}
46
203
  interface ObjectOptions extends AssistOptions {}
47
- interface ReferenceBaseOptions extends AssistOptions {}
204
+ interface ReferenceBaseOptions {
205
+ aiWritingAssistance?: {
206
+ /** Set to true to disable assistance for this field or type */
207
+ exclude?: boolean
208
+ /**
209
+ * When set, the reference field will allow instructions to be added to it.
210
+ * Should be the name of the embeddings-index where assist will look for contextually relevant documents
211
+ * */
212
+ embeddingsIndex?: string
213
+ }
214
+ }
48
215
  interface SlugOptions extends AssistOptions {}
49
216
  interface StringOptions extends AssistOptions {}
50
217
  interface TextOptions extends AssistOptions {}