@sanity/assist 6.1.13 → 6.1.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +210 -48
- package/dist/index.js +69 -8
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -34,9 +34,13 @@
|
|
|
34
34
|
- [Adding translation actions to fields](#adding-translation-actions-to-fields)
|
|
35
35
|
- [Translation style guide](#translation-style-guide)
|
|
36
36
|
- [Custom field actions](#custom-field-actions)
|
|
37
|
-
- [useExampleFieldActions](#
|
|
37
|
+
- [useExampleFieldActions](#useexamplefieldactions)
|
|
38
38
|
- [Define helpers](#define-helpers)
|
|
39
39
|
- [useUserInput](#useuserinput)
|
|
40
|
+
- [Known limitations](#known-limitations)
|
|
41
|
+
- [Image descriptions are always generated in English](#image-descriptions-are-always-generated-in-english)
|
|
42
|
+
- [Caveats](#caveats)
|
|
43
|
+
- [Third party sub-processors](#third-party-sub-processors)
|
|
40
44
|
- [License](#license)
|
|
41
45
|
|
|
42
46
|
## About Sanity AI Assist
|
|
@@ -46,7 +50,8 @@ You create the instructions; Sanity AI Assist does the rest. [Learn more about w
|
|
|
46
50
|
[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=)
|
|
47
51
|
|
|
48
52
|
> 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.
|
|
49
|
-
|
|
53
|
+
|
|
54
|
+
<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">
|
|
50
55
|
|
|
51
56
|
## Installation
|
|
52
57
|
|
|
@@ -106,16 +111,23 @@ export default defineConfig({
|
|
|
106
111
|
After installing and adding the plugin and having the AI Assist feature enabled for your project and its datasets, you need to create a token for the plugin to access the AI Assist API. This needs to be done by a member of the project with token creation permissions (typically someone with an admin or developer role).
|
|
107
112
|
|
|
108
113
|
- Start the studio and open any document
|
|
109
|
-
- Click
|
|
114
|
+
- Click **the sparkle icon** (✨) in the document header near the close document X-button
|
|
110
115
|
- Then select **Manage instructions**
|
|
116
|
+
|
|
111
117
|
<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">
|
|
118
|
+
|
|
112
119
|
- Selecting **Manage instructions** will open an inspector panel
|
|
113
120
|
- Click the **Enable AI assistance** button to create a token and enable AI Assist for everyone with access to the project
|
|
121
|
+
|
|
114
122
|
<img width="339" alt="The 'Enable Sanity AI Assist' button" src="https://github.com/sanity-io/sanity/assets/835514/38b81861-6a7c-49a2-a7c5-f46816d0c0a8">
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
123
|
+
|
|
124
|
+
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).
|
|
125
|
+
|
|
126
|
+
<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" />
|
|
127
|
+
|
|
128
|
+
The plugin will now work for any dataset in your project.
|
|
129
|
+
|
|
130
|
+
> **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.
|
|
119
131
|
|
|
120
132
|
### Permissions
|
|
121
133
|
|
|
@@ -177,7 +189,8 @@ assist({
|
|
|
177
189
|
- `localeSettings`: See section on [date and datetime](#date-and-datetime)
|
|
178
190
|
- `maxPathDepth`: The max depth for document paths AI Assist will write to.
|
|
179
191
|
- `temperature`: Influences how much the output of an instruction will vary between runs.
|
|
180
|
-
|
|
192
|
+
|
|
193
|
+
For more details, please review the TSDocs of the individual config parameters in [assistTypes.ts](./src/assistTypes.ts).
|
|
181
194
|
|
|
182
195
|
## Schema configuration
|
|
183
196
|
|
|
@@ -245,21 +258,23 @@ The following types are not supported, and behave as excluded types:
|
|
|
245
258
|
- [Image](https://www.sanity.io/docs/image-type) (supported when image has custom fields)
|
|
246
259
|
- [File](https://www.sanity.io/docs/file-type) (never supported, even when file has custom fields)
|
|
247
260
|
- [Reference](https://www.sanity.io/docs/reference-type) (supported when configured with embeddingsIndex)
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
261
|
+
|
|
262
|
+
Fields with these types will not be changed by the assistant, do not have AI Assist actions, and cannot be referenced in instructions.
|
|
263
|
+
Objects where all fields are excluded or unsupported and arrays where all member types are excluded or unsupported
|
|
264
|
+
will also be excluded.
|
|
251
265
|
|
|
252
266
|
### Date and datetime
|
|
253
267
|
|
|
254
268
|
- [Date](https://www.sanity.io/docs/date-type)
|
|
255
269
|
- [Datetime](https://www.sanity.io/docs/datetime-type)
|
|
256
|
-
Starting from v3.0.0, AI Assist can write to date and datetime fields. Instructions can use language like "tomorrow at noon" or
|
|
257
|
-
"next year", and when Assist writes to the field, it will be converted to a field-compatible value.
|
|
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
|
-
Alternatively, you can configure the plugin per user with an `assist.localeSettings` function that should return `LocaleSettings`.
|
|
261
270
|
|
|
262
|
-
|
|
271
|
+
Starting from v3.0.0, AI Assist can write to date and datetime fields. Instructions can use language like "tomorrow at noon" or
|
|
272
|
+
"next year", and when Assist writes to the field, it will be converted to a field-compatible value.
|
|
273
|
+
Language about time is locale and timeZone dependant. By default instructions will use the locale and timezone provided
|
|
274
|
+
by the browser (`Intl.DateTimeFormat().resolvedOptions()`).
|
|
275
|
+
Alternatively, you can configure the plugin per user with an `assist.localeSettings` function that should return `LocaleSettings`.
|
|
276
|
+
|
|
277
|
+
#### Example
|
|
263
278
|
|
|
264
279
|
```ts
|
|
265
280
|
assist({
|
|
@@ -403,23 +418,34 @@ By default, the caption field will regenerate whenever the image asset changes.
|
|
|
403
418
|
}
|
|
404
419
|
```
|
|
405
420
|
|
|
421
|
+
> **Note:** Image descriptions are always generated in English.
|
|
422
|
+
> See [Known limitations](#image-descriptions-are-always-generated-in-english) for details and workarounds.
|
|
423
|
+
|
|
406
424
|
## Image generation
|
|
407
425
|
|
|
408
426
|
<img width="600" alt="image" src="https://github.com/sanity-io/assist/assets/835514/c4de6791-f530-4cd1-b0c2-96ef988bc256">
|
|
427
|
+
|
|
409
428
|
AI Assist can generate assets for images configured with a prompt field.
|
|
410
429
|
An image is generated directly by using the **Generate image from prompt** instruction on the prompt field,
|
|
411
430
|
or indirectly whenever the image prompt field is written to by an AI Assist instruction.
|
|
431
|
+
|
|
412
432
|
### Configure
|
|
433
|
+
|
|
413
434
|
To enable image generation for an image field, the image must:
|
|
435
|
+
|
|
414
436
|
- set `options.aiAssist.imageInstructionField` to a child-path relative to the image
|
|
415
437
|
- have a `string` or `text` field that corresponds to the `imageInstructionField` path
|
|
438
|
+
|
|
416
439
|
This will add a **Generate image from prompt** instruction to the image prompt field. Running it will generate an image.
|
|
417
440
|
Additionally, whenever an AI Assist instruction writes to the image prompt field, the image will be re-generated.
|
|
418
441
|
This could be a document instruction, an instruction for the image field or parent object, or directly on the image prompt field.
|
|
419
442
|
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.
|
|
420
443
|
Use AI context documents to apply a reusable style guide to the prompt rewriting as needed.
|
|
444
|
+
|
|
421
445
|
#### Example
|
|
446
|
+
|
|
422
447
|
Given the following document schema
|
|
448
|
+
|
|
423
449
|
```ts
|
|
424
450
|
defineType({
|
|
425
451
|
type: 'document',
|
|
@@ -445,13 +471,18 @@ defineType({
|
|
|
445
471
|
],
|
|
446
472
|
})
|
|
447
473
|
```
|
|
474
|
+
|
|
448
475
|
To directly generate an image based on the value in the prompt field,
|
|
449
476
|
run the "Generate image from prompt" instruction that is automatically added.
|
|
450
477
|
For better image results or to ensure a consistent style, rewrite the prompt before generating the image:
|
|
478
|
+
|
|
451
479
|
### Example prompt expansion instruction
|
|
480
|
+
|
|
452
481
|
<img width="267" alt="image" src="https://github.com/sanity-io/assist/assets/835514/dabc6910-80d3-4a69-940f-49ac5cae9ade">
|
|
482
|
+
|
|
453
483
|
For better image results, use an instruction that expands the prompt to be more detailed.
|
|
454
484
|
Example instruction text:
|
|
485
|
+
|
|
455
486
|
```
|
|
456
487
|
Rewrite image prompts for image generation according to the following rules:
|
|
457
488
|
- 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".
|
|
@@ -465,22 +496,31 @@ Keep it 100 words or less.
|
|
|
465
496
|
The prompt to rewrite is:
|
|
466
497
|
{Reference to image-prompt-field}
|
|
467
498
|
```
|
|
499
|
+
|
|
468
500
|
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.
|
|
501
|
+
|
|
469
502
|
## Full document translation
|
|
503
|
+
|
|
470
504
|
<img width="250" alt="Translate document action" src="https://github.com/sanity-io/assist/assets/835514/932968ee-1a8c-4389-8822-338188f88b40">
|
|
505
|
+
|
|
471
506
|
AI assist offers full document translations, which is ideal for pairing with [@sanity/document-internationalization](https://github.com/sanity-io/document-internationalization).
|
|
472
507
|
Translations are done deeply; visiting nested objects, arrays and even Portable text annotations.
|
|
508
|
+
|
|
473
509
|
### What AI Assist full document translations solves
|
|
510
|
+
|
|
474
511
|
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.
|
|
475
512
|
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.
|
|
476
513
|
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.
|
|
477
514
|
AI Assist allows editors to translate these documents into the desired language immediately.
|
|
515
|
+
|
|
478
516
|
### Configure document translations
|
|
517
|
+
|
|
479
518
|
To enable full document translations, set `translate.document.languageField` to the path of the language field in your documents.
|
|
480
519
|
All documents with a corresponding language field will get a "Translate document" instruction added to the AI Assist drop-down for the document.
|
|
481
520
|
To further limit which document types should be enabled for translation instructions, provide an array of document type names to `translate.document.documentTypes`.
|
|
482
521
|
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.
|
|
483
522
|
**Example configs**
|
|
523
|
+
|
|
484
524
|
```ts
|
|
485
525
|
// This will add a "Translate document" instruction to all documents with a language field
|
|
486
526
|
assist({
|
|
@@ -491,6 +531,7 @@ assist({
|
|
|
491
531
|
},
|
|
492
532
|
})
|
|
493
533
|
```
|
|
534
|
+
|
|
494
535
|
```ts
|
|
495
536
|
// This will add a "Translate document" instruction only to the 'article' document type
|
|
496
537
|
assist({
|
|
@@ -502,7 +543,9 @@ assist({
|
|
|
502
543
|
},
|
|
503
544
|
})
|
|
504
545
|
```
|
|
546
|
+
|
|
505
547
|
**All configuration params**
|
|
548
|
+
|
|
506
549
|
```ts
|
|
507
550
|
assist({
|
|
508
551
|
translate: {
|
|
@@ -531,17 +574,25 @@ assist({
|
|
|
531
574
|
}
|
|
532
575
|
})
|
|
533
576
|
```
|
|
577
|
+
|
|
534
578
|
## Field level translations
|
|
579
|
+
|
|
535
580
|
<img width="250" alt="Translate fields action" src="https://github.com/sanity-io/assist/assets/835514/99819cd4-578e-43b2-8c70-8e39afff5f09">
|
|
536
581
|
<img width="250" alt="Translate fields dialog" src="https://github.com/sanity-io/assist/assets/835514/fe3d289c-49b6-46dd-ae2f-cd509a01534a">
|
|
582
|
+
|
|
537
583
|
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)
|
|
584
|
+
|
|
538
585
|
### What AI Assist field-level translations solves
|
|
586
|
+
|
|
539
587
|
Given a document with field values in different languages, AI assist can transfer and translate from one language to the others.
|
|
540
588
|
The typical use case would be for documents that use internationalized wrapper types to hold values for multiple languages.
|
|
541
589
|
AI Assist supports complex values, so language fields that hold nested objects, portable text, or arrays will also be translated.
|
|
542
590
|
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.
|
|
591
|
+
|
|
543
592
|
### Configure field translations
|
|
593
|
+
|
|
544
594
|
To enable field-level translations, set `translate.field.documentTypes` to an array with which document types should get field translations, and `translate.field.languages`
|
|
595
|
+
|
|
545
596
|
```ts
|
|
546
597
|
assist({
|
|
547
598
|
translate: {
|
|
@@ -555,10 +606,12 @@ assist({
|
|
|
555
606
|
},
|
|
556
607
|
})
|
|
557
608
|
```
|
|
609
|
+
|
|
558
610
|
These documents will get a **Translate fields** instruction added to the document AI Assist dropdown.
|
|
559
611
|
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).
|
|
560
612
|
It will also work without further config for object types named `locale*`, (e.g. `localeTitle`, `localeDescription`) with one field per language:
|
|
561
613
|
_Example locale object supported by default_
|
|
614
|
+
|
|
562
615
|
```ts
|
|
563
616
|
// Object type with name starting with 'locale', and one field per language language
|
|
564
617
|
defineType({
|
|
@@ -579,26 +632,36 @@ defineType({
|
|
|
579
632
|
],
|
|
580
633
|
})
|
|
581
634
|
```
|
|
635
|
+
|
|
582
636
|
**If your schema is not using either of these structures**, refer to the section on [Custom language fields](#custom-language-fields).
|
|
637
|
+
|
|
583
638
|
#### Note on document schema depth
|
|
639
|
+
|
|
584
640
|
By default, field level translations will translate 6 "path-segments" deep.
|
|
585
641
|
Depth is based on field path segments like so:
|
|
642
|
+
|
|
586
643
|
- `title` has depth 1
|
|
587
644
|
- `array[_key="no"].title` has depth 3
|
|
645
|
+
|
|
588
646
|
If this is not sufficient for your document types, use `maxPathDepth`:
|
|
647
|
+
|
|
589
648
|
```ts
|
|
590
649
|
assist({
|
|
591
650
|
translate: {
|
|
592
651
|
field: {
|
|
593
|
-
maxPathDepth: 12
|
|
652
|
+
maxPathDepth: 12,
|
|
594
653
|
},
|
|
595
654
|
},
|
|
596
655
|
})
|
|
597
656
|
```
|
|
657
|
+
|
|
598
658
|
Be careful not to set this too high in studios with recursive document schemas, as it could have negative impact on performance.
|
|
599
659
|
maxPathDepth is hard-capped to 50.
|
|
660
|
+
|
|
600
661
|
### Loading field languages
|
|
662
|
+
|
|
601
663
|
Languages must be an array of objects with an id and title.
|
|
664
|
+
|
|
602
665
|
```ts
|
|
603
666
|
assist({
|
|
604
667
|
translate: {
|
|
@@ -611,7 +674,9 @@ assist({
|
|
|
611
674
|
},
|
|
612
675
|
})
|
|
613
676
|
```
|
|
677
|
+
|
|
614
678
|
Or an asynchronous function that returns an array of objects with an id and title.
|
|
679
|
+
|
|
615
680
|
```ts
|
|
616
681
|
assist({
|
|
617
682
|
translate: {
|
|
@@ -624,7 +689,9 @@ assist({
|
|
|
624
689
|
},
|
|
625
690
|
})
|
|
626
691
|
```
|
|
692
|
+
|
|
627
693
|
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.
|
|
694
|
+
|
|
628
695
|
```ts
|
|
629
696
|
assist({
|
|
630
697
|
translate: {
|
|
@@ -637,8 +704,10 @@ assist({
|
|
|
637
704
|
},
|
|
638
705
|
})
|
|
639
706
|
```
|
|
707
|
+
|
|
640
708
|
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.
|
|
641
709
|
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.
|
|
710
|
+
|
|
642
711
|
```ts
|
|
643
712
|
assist({
|
|
644
713
|
translate: {
|
|
@@ -657,21 +726,30 @@ assist({
|
|
|
657
726
|
},
|
|
658
727
|
})
|
|
659
728
|
```
|
|
729
|
+
|
|
660
730
|
### Custom language fields
|
|
731
|
+
|
|
661
732
|
By providing a function to `translate.field.translationOutputs`, you have complete control over which fields belong to which language.
|
|
662
733
|
`translationOutputs` is used when an editor uses the **Translate fields** instruction.
|
|
663
734
|
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.
|
|
664
735
|
`translationOutputs` is invoked once per path in the document (limited to a depth of 6), with the following arguments:
|
|
736
|
+
|
|
665
737
|
- `documentMember` - the field or array item for a given path; contains the path and its `schemaType`
|
|
666
738
|
- `enclosingType` - the schema type of the parent holding the member
|
|
667
739
|
- `translateFromLanguageId` - the `languageId` for the language the users want to translate from
|
|
668
740
|
- `translateToLanguageIds` - all `languageId`s the user can translate to
|
|
741
|
+
|
|
669
742
|
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.
|
|
670
743
|
The function should return `undefined` for all document members that should not be directly translated, or are nested fields under a translated path.
|
|
744
|
+
|
|
671
745
|
#### Default function
|
|
746
|
+
|
|
672
747
|
The default `translationOutputs` is available using `import {defaultTranslationOutputs} from '@sanity/assist`.
|
|
748
|
+
|
|
673
749
|
#### Example
|
|
750
|
+
|
|
674
751
|
Given the following document:
|
|
752
|
+
|
|
675
753
|
```ts
|
|
676
754
|
{
|
|
677
755
|
titles: {
|
|
@@ -687,19 +765,25 @@ Given the following document:
|
|
|
687
765
|
}
|
|
688
766
|
}
|
|
689
767
|
```
|
|
768
|
+
|
|
690
769
|
When translating from English to German, `translationOutputs` will be
|
|
691
770
|
invoked multiple times.
|
|
692
771
|
The following parameters will be the same every invocation:
|
|
772
|
+
|
|
693
773
|
- `translateFromLanguageId` will be `'en'`
|
|
694
774
|
- `translateToLanguageIds` will be `['de']`
|
|
775
|
+
|
|
695
776
|
`documentMember` and `enclosingType` will change between each invocation, and take the following values:
|
|
777
|
+
|
|
696
778
|
1. `{path: 'titles', name: 'titles', schemaType: ObjectSchemaType}`, `ObjectSchemaType`
|
|
697
779
|
2. `{path: 'titles.en', name: 'en', schemaType: ObjectSchemaType}`, `ObjectSchemaType`
|
|
698
780
|
3. `{path: 'titles.en.title', name: 'title', schemaType: StringSchemaType}`, `ObjectSchemaType`
|
|
699
781
|
4. `{path: 'titles.en.subtitle', name: 'subtitle', schemaType: StringSchemaType}`, `ObjectSchemaType`
|
|
700
782
|
5. `{path: 'titles.de', name: 'de', schemaType: ObjectSchemaType}`, `ObjectSchemaType`
|
|
783
|
+
|
|
701
784
|
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'`.
|
|
702
785
|
The following function enables this:
|
|
786
|
+
|
|
703
787
|
```ts
|
|
704
788
|
function translationOutputs(
|
|
705
789
|
member,
|
|
@@ -722,7 +806,9 @@ function translationOutputs(
|
|
|
722
806
|
return undefined
|
|
723
807
|
}
|
|
724
808
|
```
|
|
725
|
-
|
|
809
|
+
|
|
810
|
+
### Full field translation configuration example
|
|
811
|
+
|
|
726
812
|
```ts
|
|
727
813
|
assist({
|
|
728
814
|
translate: {
|
|
@@ -756,16 +842,21 @@ assist({
|
|
|
756
842
|
},
|
|
757
843
|
})
|
|
758
844
|
```
|
|
845
|
+
|
|
759
846
|
## Adding translation actions to fields
|
|
847
|
+
|
|
760
848
|
<img width="250" alt="Translate action on field" src="https://github.com/sanity-io/assist/assets/835514/e6dc0860-90a7-4f7a-b3d2-71893b09862f">
|
|
761
849
|
<img width="250" alt="Translate fields action on field" src="https://github.com/sanity-io/assist/assets/835514/acc5fa23-2022-4eae-922d-5c83dda7379c">
|
|
850
|
+
|
|
762
851
|
By default, **Translate document** and **Translate fields…** instructions are only added to the top-level document instruction menu.
|
|
763
852
|
These instructions can also be added to fields by setting
|
|
764
853
|
`options.aiAssist.translateAction: true` for a field or type.
|
|
765
854
|
This allows editors to translate only parts of the document and can be useful to enable for `internationalizedArrays` or `locale` wrapper object types.
|
|
766
855
|
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
|
|
767
856
|
For document types configured for field translations, a **Translate fields...** action will be added. Running it will open a dialog with language selectors.
|
|
857
|
+
|
|
768
858
|
#### Example
|
|
859
|
+
|
|
769
860
|
```ts
|
|
770
861
|
defineField({
|
|
771
862
|
name: 'subtitle',
|
|
@@ -778,11 +869,14 @@ defineField({
|
|
|
778
869
|
},
|
|
779
870
|
})
|
|
780
871
|
```
|
|
872
|
+
|
|
781
873
|
## Translation style guide
|
|
874
|
+
|
|
782
875
|
In some cases you might want/need the translator to follow a certain style guide - for
|
|
783
876
|
instance you might tell it not to translate certain words, or be more formal or casual.
|
|
784
877
|
To configure this you can pass a `styleguide` property under the translation
|
|
785
878
|
configuration:
|
|
879
|
+
|
|
786
880
|
```ts
|
|
787
881
|
assist({
|
|
788
882
|
translate: {
|
|
@@ -790,42 +884,55 @@ assist({
|
|
|
790
884
|
},
|
|
791
885
|
})
|
|
792
886
|
```
|
|
887
|
+
|
|
793
888
|
The style guide is currently limited to 2000 characters, and the translation might get
|
|
794
889
|
slower the longer your style guide is. If the provided string is longer than the limit,
|
|
795
890
|
the plugin will throw upon studio startup.
|
|
796
891
|
Note that this is currently only available on a global level - it can not be defined
|
|
797
892
|
per-field for now.
|
|
893
|
+
|
|
798
894
|
### Dynamic styleguide
|
|
895
|
+
|
|
799
896
|
As of 4.1.0 it is also possible to provide a styleguide async function.
|
|
800
|
-
The function is passed a context object with Sanity client and the current documentId and schemaType.
|
|
897
|
+
The function is passed a context object with Sanity client and the current documentId and schemaType.
|
|
801
898
|
Consider caching the results: the function is invoked every time translate runs.
|
|
899
|
+
|
|
802
900
|
```ts
|
|
803
901
|
assist({
|
|
804
902
|
translate: {
|
|
805
|
-
styleguide: ({client, documentId, schemaType}) =>
|
|
903
|
+
styleguide: ({client, documentId, schemaType}) =>
|
|
904
|
+
client.fetch('* [_id=="styleguide.singleton"][0].styleguide'),
|
|
806
905
|
},
|
|
807
906
|
})
|
|
808
907
|
```
|
|
908
|
+
|
|
809
909
|
## Custom field actions
|
|
910
|
+
|
|
810
911
|
<img width="513" alt="Field action menu with custom actions" src="https://github.com/user-attachments/assets/c613f692-4983-4acc-a8c2-8fb60294682a" />
|
|
912
|
+
|
|
811
913
|
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=)
|
|
812
914
|
or other custom actions into the AI Assist document and field action menus, use `fieldActions` plugin config.
|
|
813
915
|
Because of react hook linting, we recommend defining the `useExampleFieldActions` outside the plugin config:
|
|
916
|
+
|
|
814
917
|
```ts
|
|
815
918
|
//sanity.config.ts
|
|
816
919
|
import {defineConfig} from 'sanity'
|
|
817
920
|
import {assist, type AssistFieldActionProps, defineAssistFieldAction} from '@sanity/assist'
|
|
818
921
|
function useExampleFieldActions(props: AssistFieldActionProps) {
|
|
819
|
-
return useMemo(
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
922
|
+
return useMemo(
|
|
923
|
+
() => [
|
|
924
|
+
defineAssistFieldAction({
|
|
925
|
+
title: 'Do something',
|
|
926
|
+
icon: ActionIcon,
|
|
927
|
+
onAction: async () => {
|
|
928
|
+
// perform an (async) action
|
|
929
|
+
// errors will be caught and displayed in a toast
|
|
930
|
+
// until the action completes or fails, AI Assist "presence" will show up on the top of the document
|
|
931
|
+
},
|
|
932
|
+
}),
|
|
933
|
+
],
|
|
934
|
+
[],
|
|
935
|
+
)
|
|
829
936
|
}
|
|
830
937
|
export default defineConfig({
|
|
831
938
|
//...
|
|
@@ -834,26 +941,33 @@ export default defineConfig({
|
|
|
834
941
|
assist({
|
|
835
942
|
fieldActions: {
|
|
836
943
|
title: 'Custom actions',
|
|
837
|
-
useExampleFieldActions
|
|
838
|
-
}
|
|
839
|
-
})
|
|
840
|
-
]
|
|
944
|
+
useExampleFieldActions,
|
|
945
|
+
},
|
|
946
|
+
}),
|
|
947
|
+
],
|
|
841
948
|
})
|
|
842
949
|
```
|
|
950
|
+
|
|
843
951
|
### `useExampleFieldActions`
|
|
952
|
+
|
|
844
953
|
`useExampleFieldActions` is called for the document itself and for all fields within it. It can call React hooks.
|
|
845
954
|
Actions returned by the hook will be added to the corresponding document or field menu.
|
|
846
|
-
It is recommended to wrap the returned actions in `useMemo`. The returned array can contain `undefined` values.
|
|
955
|
+
It is recommended to wrap the returned actions in `useMemo`. The returned array can contain `undefined` values.
|
|
847
956
|
These will be filtered out.
|
|
848
957
|
See TSDocs for [AssistFieldActionProps](./src/fieldActions/customFieldActions.tsx) for details on how each
|
|
849
958
|
prop can be used to parameterize Agent Actions on sanity client.
|
|
959
|
+
|
|
850
960
|
#### Agent Action examples
|
|
961
|
+
|
|
851
962
|
Below are some examples of agent action integration.
|
|
852
|
-
For more, see [HOW-TO-USE](
|
|
963
|
+
For more, see [HOW-TO-USE](https://github.com/sanity-io/assist/blob/main/studio/examples/agentActions/HOW-TO-USE.md).
|
|
964
|
+
|
|
853
965
|
##### Fix spelling
|
|
966
|
+
|
|
854
967
|
The following example adds a "Fix spelling" action to all fields and the document itself.
|
|
855
968
|
It will fix spelling mistakes for the field it is invoked for (and all child fields, for arrays and objects),
|
|
856
969
|
by calling `client.agent.action.transform`.
|
|
970
|
+
|
|
857
971
|
```ts
|
|
858
972
|
function useExampleFieldActions(props: AssistFieldActionProps) {
|
|
859
973
|
const {
|
|
@@ -894,13 +1008,17 @@ function useExampleFieldActions(props: AssistFieldActionProps) {
|
|
|
894
1008
|
])
|
|
895
1009
|
}
|
|
896
1010
|
```
|
|
1011
|
+
|
|
897
1012
|
##### Fill field (contextually aware)
|
|
1013
|
+
|
|
898
1014
|
The following example adds a "Fill field" action to all fields in the document by calling `client.agent.action.generate`.
|
|
899
1015
|
The action will:
|
|
1016
|
+
|
|
900
1017
|
- create the document as a draft if it does not exist, respecting initial values (`targetDocument`)
|
|
901
1018
|
- use existing document state to determine what should be put in the the field (`instruction`, `instructionParams`)
|
|
902
1019
|
- pass the current readOnly and hidden state currently use by the document form to the Agent Action, so it respects it (`conditionalPaths`)
|
|
903
1020
|
- output to the field the action started from (`target.path`)
|
|
1021
|
+
|
|
904
1022
|
```ts
|
|
905
1023
|
function useExampleFieldActions(props: AssistFieldActionProps) {
|
|
906
1024
|
const {
|
|
@@ -976,10 +1094,14 @@ function useExampleFieldActions(props: AssistFieldActionProps) {
|
|
|
976
1094
|
])
|
|
977
1095
|
}
|
|
978
1096
|
```
|
|
1097
|
+
|
|
979
1098
|
### Define helpers
|
|
1099
|
+
|
|
980
1100
|
#### `defineAssistFieldAction`
|
|
1101
|
+
|
|
981
1102
|
Adds a single action that will appear in the document/field action menu.
|
|
982
1103
|
`onAction` _cannot_ call hooks. If state from hook is needed, it should be pre-assembled by `useExampleFieldActions`
|
|
1104
|
+
|
|
983
1105
|
```ts
|
|
984
1106
|
defineAssistFieldAction({
|
|
985
1107
|
title: 'Do something',
|
|
@@ -989,44 +1111,57 @@ defineAssistFieldAction({
|
|
|
989
1111
|
},
|
|
990
1112
|
})
|
|
991
1113
|
```
|
|
1114
|
+
|
|
992
1115
|
#### `defineAssistFieldActionGroup`
|
|
1116
|
+
|
|
993
1117
|
Adds a group to hold one or more actions (or nested groups).
|
|
994
1118
|
`children` can contain `undefined` values. These will be filtered out.
|
|
995
1119
|
A group that has an empty `children` array (or only undefined values) will be filtered out.
|
|
996
1120
|
By default, any actions returned by `useExampleFieldActions` will be grouped under `title`.
|
|
1121
|
+
|
|
997
1122
|
```ts
|
|
998
1123
|
function useExampleFieldActions(props: AssistFieldActionProps) {
|
|
999
1124
|
return [
|
|
1000
|
-
defineAssistFieldAction({/* ... */}),
|
|
1125
|
+
defineAssistFieldAction({/* ... */}),
|
|
1001
1126
|
defineAssistFieldActionGroup({
|
|
1002
1127
|
title: 'More actions',
|
|
1003
|
-
children: [
|
|
1004
|
-
|
|
1005
|
-
],
|
|
1006
|
-
})
|
|
1128
|
+
children: [defineAssistFieldAction({/* ... */})],
|
|
1129
|
+
}),
|
|
1007
1130
|
]
|
|
1008
1131
|
}
|
|
1009
1132
|
```
|
|
1133
|
+
|
|
1010
1134
|
#### Only groups in `useExampleFieldActions`
|
|
1135
|
+
|
|
1011
1136
|
If `useExampleFieldActions` _only_ returns groups, the default wrapper group will be omitted. This allows full control over each group title.
|
|
1137
|
+
|
|
1012
1138
|
#### `defineFieldActionDivider`
|
|
1139
|
+
|
|
1013
1140
|
Adds a divider between actions or groups. Takes no arguments:
|
|
1141
|
+
|
|
1014
1142
|
```ts
|
|
1015
1143
|
function useExampleFieldActions(props: AssistFieldActionProps) {
|
|
1016
|
-
return useMemo(
|
|
1017
|
-
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1144
|
+
return useMemo(
|
|
1145
|
+
() => [
|
|
1146
|
+
defineAssistFieldAction({/* ... */}),
|
|
1147
|
+
defineFieldActionDivider(),
|
|
1148
|
+
defineAssistFieldAction({/* ... */}),
|
|
1149
|
+
],
|
|
1150
|
+
[],
|
|
1151
|
+
)
|
|
1021
1152
|
}
|
|
1022
1153
|
```
|
|
1154
|
+
|
|
1023
1155
|
### `useUserInput`
|
|
1156
|
+
|
|
1024
1157
|
<img width="522" alt="user input dialog" src="https://github.com/user-attachments/assets/86966468-9a28-4c0b-99f3-e4b80fdbe691" />
|
|
1158
|
+
|
|
1025
1159
|
For certain actions, it is useful to have the user provide additional information or details that can be used
|
|
1026
1160
|
as parameters for the action.
|
|
1027
1161
|
`useUserInput` returns a `getUserInput` function that can be called and awaited to return input from the user.
|
|
1028
1162
|
The `getUserInput` function takes input configuration and will display an input dialog to the user.
|
|
1029
1163
|
When the user completes the dialog, the user inputted text will be available (or undefined if the user closed the dialog).
|
|
1164
|
+
|
|
1030
1165
|
```ts
|
|
1031
1166
|
function useExampleFieldActions(props: AssistFieldActionProps) {
|
|
1032
1167
|
const getUserInput = useUserInput()
|
|
@@ -1061,13 +1196,40 @@ function useExampleFieldActions(props: AssistFieldActionProps) {
|
|
|
1061
1196
|
)
|
|
1062
1197
|
}
|
|
1063
1198
|
```
|
|
1199
|
+
|
|
1200
|
+
## Known limitations
|
|
1201
|
+
|
|
1202
|
+
### Image descriptions are always generated in English
|
|
1203
|
+
|
|
1204
|
+
The AI Assist API currently ignores the document language when generating image descriptions:
|
|
1205
|
+
fields configured with `options.aiAssist.imageDescriptionField` always get an English description,
|
|
1206
|
+
even when [document translation](#configure-document-translations) is configured with `translate.document.languageField`.
|
|
1207
|
+
This is a limitation in the AI Assist API itself, so it cannot be worked around with plugin or Studio configuration
|
|
1208
|
+
(see [sanity-io/plugins#1606](https://github.com/sanity-io/plugins/issues/1606)).
|
|
1209
|
+
|
|
1210
|
+
If you need image descriptions in another language, consider one of these alternatives:
|
|
1211
|
+
|
|
1212
|
+
- Use the [Transform Agent Action's `image-description` operation](https://www.sanity.io/docs/agent-actions/targets-paths#image-description)
|
|
1213
|
+
with a custom `instruction` that specifies the output language, for example via a
|
|
1214
|
+
[custom field action](#custom-field-actions) or a [Sanity Function](https://www.sanity.io/docs/functions),
|
|
1215
|
+
instead of `imageDescriptionField`.
|
|
1216
|
+
- Keep `imageDescriptionField` and let editors run the document or field translation actions afterwards,
|
|
1217
|
+
translating the generated English description along with the rest of the document
|
|
1218
|
+
(see [Full document translation](#full-document-translation) and [Field level translations](#field-level-translations)).
|
|
1219
|
+
|
|
1064
1220
|
## Caveats
|
|
1221
|
+
|
|
1065
1222
|
Large Language Models (LLMs) are a new technology. Constraints and limitations are still being explored,
|
|
1066
1223
|
but some common caveats to the field that you may run into using AI Assist are:
|
|
1224
|
+
|
|
1067
1225
|
- Limits to instruction length: Long instructions on deep content structures may exhaust model context
|
|
1068
1226
|
- Timeouts: To be able to write structured content, we're using the largest language models - long-running results may time out or intermittently fail
|
|
1069
1227
|
- Limited capacity: The underlying LLM APIs used by AI Assist are resource-constrained
|
|
1228
|
+
|
|
1070
1229
|
## Third party sub-processors
|
|
1230
|
+
|
|
1071
1231
|
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.
|
|
1232
|
+
|
|
1072
1233
|
## License
|
|
1073
|
-
|
|
1234
|
+
|
|
1235
|
+
[MIT](https://github.com/sanity-io/plugins/blob/main/LICENSE) © Sanity.io
|