@sanity/assist 4.2.0 → 4.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +299 -0
- package/dist/index.d.mts +265 -0
- package/dist/index.d.ts +265 -0
- package/dist/index.esm.js +232 -99
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +227 -94
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +232 -99
- package/dist/index.mjs.map +1 -1
- package/package.json +9 -8
- package/src/assistDocument/AssistDocumentContext.tsx +14 -1
- package/src/assistDocument/hooks/useAssistDocumentContextValue.tsx +30 -3
- package/src/assistLayout/RunInstructionProvider.tsx +75 -23
- package/src/fieldActions/assistFieldActions.tsx +42 -2
- package/src/fieldActions/customFieldActions.tsx +304 -0
- package/src/fieldActions/useUserInput.ts +107 -0
- package/src/helpers/typeUtils.ts +6 -0
- package/src/index.ts +19 -0
- package/src/plugin.tsx +6 -0
- package/src/presence/AssistDocumentPresence.tsx +3 -3
package/README.md
CHANGED
|
@@ -34,6 +34,10 @@
|
|
|
34
34
|
- [Configure](#configure-field-translations)
|
|
35
35
|
- [Adding translation actions to fields](#adding-translation-actions-to-fields)
|
|
36
36
|
- [Translation style guide](#translation-style-guide)
|
|
37
|
+
- [Custom field actions](#custom-field-actions)
|
|
38
|
+
- [useFieldActions](#usefieldaction)
|
|
39
|
+
- [Define helpers](#define-helpers)
|
|
40
|
+
- [useUserInput](#useuserinput)
|
|
37
41
|
- [License](#license)
|
|
38
42
|
- [Develop \& test](#develop--test)
|
|
39
43
|
- [Release new version](#release-new-version)
|
|
@@ -940,6 +944,301 @@ assist({
|
|
|
940
944
|
})
|
|
941
945
|
```
|
|
942
946
|
|
|
947
|
+
## Custom field actions
|
|
948
|
+
|
|
949
|
+
<img width="513" alt="Field action menu with custom actions" src="https://github.com/user-attachments/assets/c613f692-4983-4acc-a8c2-8fb60294682a" />
|
|
950
|
+
|
|
951
|
+
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=)
|
|
952
|
+
or other custom actions into the AI Assist document and field action menus, use `fieldActions` plugin config:
|
|
953
|
+
|
|
954
|
+
```ts
|
|
955
|
+
assist({
|
|
956
|
+
fieldActions: {
|
|
957
|
+
title: 'Custom actions',
|
|
958
|
+
useFieldActions: (props: AssistFieldActionProps) => {
|
|
959
|
+
return useMemo(() => [
|
|
960
|
+
defineAssistFieldAction({
|
|
961
|
+
title: 'Do something',
|
|
962
|
+
icon: ActionIcon,
|
|
963
|
+
onAction: async () => {
|
|
964
|
+
// perform an (async) action
|
|
965
|
+
// errors will be caught and displayed in a toast
|
|
966
|
+
// until the action completes or fails, AI Assist "presence" will show up on the top of the document
|
|
967
|
+
},
|
|
968
|
+
})], [])
|
|
969
|
+
}
|
|
970
|
+
}
|
|
971
|
+
})
|
|
972
|
+
```
|
|
973
|
+
|
|
974
|
+
### `useFieldActions`
|
|
975
|
+
|
|
976
|
+
`useFieldActions` is called for the document itself and for all fields within it. It can call React hooks.
|
|
977
|
+
Actions returned by the hook will be added to the corresponding document or field menu.
|
|
978
|
+
|
|
979
|
+
It is recommended to wrap the returned actions in `useMemo`.
|
|
980
|
+
|
|
981
|
+
See TSDocs for [AssistFieldActionProps](./src/fieldActions/customFieldActions.tsx) for details on how each
|
|
982
|
+
prop can be used to parameterize Agent Actions on sanity client.
|
|
983
|
+
|
|
984
|
+
#### Agent Action examples
|
|
985
|
+
|
|
986
|
+
##### Fix spelling
|
|
987
|
+
|
|
988
|
+
The following example adds a "Fix spelling" action to all fields and the document itself.
|
|
989
|
+
|
|
990
|
+
It will fix spelling mistakes for the field it is invoked for (and all child fields, for arrays and objects),
|
|
991
|
+
by calling `client.agent.action.transform`.
|
|
992
|
+
|
|
993
|
+
```ts
|
|
994
|
+
assist({
|
|
995
|
+
fieldActions: {
|
|
996
|
+
title: 'Custom actions',
|
|
997
|
+
useFieldActions: (props) => {
|
|
998
|
+
const {
|
|
999
|
+
documentSchemaType,
|
|
1000
|
+
schemaId,
|
|
1001
|
+
getDocumentValue,
|
|
1002
|
+
getConditionalPaths,
|
|
1003
|
+
documentIdForAction,
|
|
1004
|
+
path,
|
|
1005
|
+
} = props
|
|
1006
|
+
const client = useClient({apiVersion: 'vX'})
|
|
1007
|
+
return useMemo(() => {
|
|
1008
|
+
return [
|
|
1009
|
+
defineAssistFieldAction({
|
|
1010
|
+
title: 'Fix spelling',
|
|
1011
|
+
icon: TranslateIcon,
|
|
1012
|
+
onAction: async () => {
|
|
1013
|
+
await client.agent.action.transform({
|
|
1014
|
+
schemaId,
|
|
1015
|
+
documentId: documentIdForAction,
|
|
1016
|
+
instruction: 'Fix any spelling mistakes',
|
|
1017
|
+
instructionParams: {field: {type: 'field', path}},
|
|
1018
|
+
// no need to send path for document actions
|
|
1019
|
+
target: path.length ? {path} : undefined,
|
|
1020
|
+
conditionalPaths: {paths: getConditionalPaths()},
|
|
1021
|
+
})
|
|
1022
|
+
},
|
|
1023
|
+
}),
|
|
1024
|
+
]
|
|
1025
|
+
}, [
|
|
1026
|
+
client,
|
|
1027
|
+
documentSchemaType,
|
|
1028
|
+
schemaId,
|
|
1029
|
+
getDocumentValue,
|
|
1030
|
+
getConditionalPaths,
|
|
1031
|
+
documentIdForAction,
|
|
1032
|
+
path,
|
|
1033
|
+
])
|
|
1034
|
+
},
|
|
1035
|
+
},
|
|
1036
|
+
})
|
|
1037
|
+
```
|
|
1038
|
+
|
|
1039
|
+
##### Fill field (contextually aware)
|
|
1040
|
+
|
|
1041
|
+
The following example adds a "Fill field" action to all fields in the document by calling `client.agent.action.generate`.
|
|
1042
|
+
|
|
1043
|
+
The action will:
|
|
1044
|
+
- create the document as a draft if it does not exist, respecting initial values (`targetDocument`)
|
|
1045
|
+
- use existing document state to determine what should be put in the the field (`instruction`, `instructionParams`)
|
|
1046
|
+
- pass the current readOnly and hidden state currently use by the document form to the Agent Action, so it respects it (`conditionalPaths`)
|
|
1047
|
+
- output to the field the action started from (`target.path`)
|
|
1048
|
+
|
|
1049
|
+
```ts
|
|
1050
|
+
assist({
|
|
1051
|
+
fieldActions: {
|
|
1052
|
+
title: 'Custom actions',
|
|
1053
|
+
useFieldActions: (props) => {
|
|
1054
|
+
const {
|
|
1055
|
+
documentSchemaType,
|
|
1056
|
+
actionType,
|
|
1057
|
+
schemaId,
|
|
1058
|
+
getDocumentValue,
|
|
1059
|
+
getConditionalPaths,
|
|
1060
|
+
documentIdForAction,
|
|
1061
|
+
path,
|
|
1062
|
+
schemaType,
|
|
1063
|
+
} = props
|
|
1064
|
+
|
|
1065
|
+
// hook usage has to happen outside onAction, so preassemble state in useFieldActions and pass to useMemo
|
|
1066
|
+
const client = useClient({apiVersion: 'vX'})
|
|
1067
|
+
|
|
1068
|
+
return useMemo(() => {
|
|
1069
|
+
if (actionType === 'document') {
|
|
1070
|
+
// in this case we dont want a document action
|
|
1071
|
+
return []
|
|
1072
|
+
}
|
|
1073
|
+
|
|
1074
|
+
return [
|
|
1075
|
+
defineAssistFieldAction({
|
|
1076
|
+
title: 'Fill field',
|
|
1077
|
+
icon: EditIcon,
|
|
1078
|
+
onAction: async () => {
|
|
1079
|
+
await client.agent.action.generate({
|
|
1080
|
+
schemaId,
|
|
1081
|
+
targetDocument: {
|
|
1082
|
+
operation: 'createIfNotExists',
|
|
1083
|
+
_id: documentIdForAction,
|
|
1084
|
+
_type: documentSchemaType.name,
|
|
1085
|
+
initialValues: getDocumentValue(),
|
|
1086
|
+
},
|
|
1087
|
+
instruction: `
|
|
1088
|
+
We are generating a new value for a document field.
|
|
1089
|
+
The document type is ${documentSchemaType.name}, and the document type title is ${documentSchemaType.title}
|
|
1090
|
+
The document language is: "$lang" (use en-US if unspecified)
|
|
1091
|
+
The document value is:
|
|
1092
|
+
$doc
|
|
1093
|
+
---
|
|
1094
|
+
We are in the following field:
|
|
1095
|
+
JSON-path: ${pathToString(path)}
|
|
1096
|
+
Title: ${schemaType.title}
|
|
1097
|
+
Value: $field (consider it empty if undefined)
|
|
1098
|
+
---
|
|
1099
|
+
Generate a new field value. The new value should be relevant to the document type and context.
|
|
1100
|
+
Keep it interesting. Generate using the document language.
|
|
1101
|
+
`,
|
|
1102
|
+
instructionParams: {
|
|
1103
|
+
doc: {type: 'document'},
|
|
1104
|
+
field: {type: 'field', path},
|
|
1105
|
+
lang: {type: 'field', path: ['language']},
|
|
1106
|
+
},
|
|
1107
|
+
target: {
|
|
1108
|
+
path,
|
|
1109
|
+
},
|
|
1110
|
+
conditionalPaths: {
|
|
1111
|
+
paths: getConditionalPaths(),
|
|
1112
|
+
},
|
|
1113
|
+
})
|
|
1114
|
+
},
|
|
1115
|
+
}),
|
|
1116
|
+
]
|
|
1117
|
+
}, [
|
|
1118
|
+
client,
|
|
1119
|
+
documentSchemaType,
|
|
1120
|
+
schemaId,
|
|
1121
|
+
getDocumentValue,
|
|
1122
|
+
getConditionalPaths,
|
|
1123
|
+
documentIdForAction,
|
|
1124
|
+
actionType,
|
|
1125
|
+
path,
|
|
1126
|
+
schemaType,
|
|
1127
|
+
])
|
|
1128
|
+
},
|
|
1129
|
+
},
|
|
1130
|
+
})
|
|
1131
|
+
```
|
|
1132
|
+
|
|
1133
|
+
### Define helpers
|
|
1134
|
+
|
|
1135
|
+
#### `defineAssistFieldAction`
|
|
1136
|
+
|
|
1137
|
+
Adds a single action that will appear in the document/field action menu.
|
|
1138
|
+
|
|
1139
|
+
`onAction` _cannot_ call hooks. If state from hook is needed, it should be pre-assembled by `useFieldActions`
|
|
1140
|
+
|
|
1141
|
+
```ts
|
|
1142
|
+
defineAssistFieldAction({
|
|
1143
|
+
title: 'Do something',
|
|
1144
|
+
icon: ActionIcon,
|
|
1145
|
+
onAction: async () => {
|
|
1146
|
+
//perform actions
|
|
1147
|
+
},
|
|
1148
|
+
})
|
|
1149
|
+
```
|
|
1150
|
+
|
|
1151
|
+
#### `defineAssistFieldActionGroup`
|
|
1152
|
+
|
|
1153
|
+
Adds a group to hold one or more actions (or nested groups).
|
|
1154
|
+
|
|
1155
|
+
By default, any actions returned by `useFieldActions` will be grouped under `title`.
|
|
1156
|
+
```ts
|
|
1157
|
+
useFieldActions: (props) => {
|
|
1158
|
+
return [
|
|
1159
|
+
defineAssistFieldAction({/* ... */}),
|
|
1160
|
+
defineAssistFieldActionGroup({
|
|
1161
|
+
title: 'More actions',
|
|
1162
|
+
children: [
|
|
1163
|
+
defineAssistFieldAction({/* ... */}),
|
|
1164
|
+
],
|
|
1165
|
+
})
|
|
1166
|
+
]
|
|
1167
|
+
}
|
|
1168
|
+
```
|
|
1169
|
+
|
|
1170
|
+
#### Only groups in `useFieldActions`
|
|
1171
|
+
If `useFieldActions` _only_ returns groups, the default wrapper group will be omitted. This allows full control over each group title.
|
|
1172
|
+
|
|
1173
|
+
#### `defineFieldActionDivider`
|
|
1174
|
+
Adds a divider between actions or groups. Takes no arguments:
|
|
1175
|
+
|
|
1176
|
+
```ts
|
|
1177
|
+
|
|
1178
|
+
useFieldActions: (props) => {
|
|
1179
|
+
return useMemo(() => [
|
|
1180
|
+
defineAssistFieldAction({/* ... */}),
|
|
1181
|
+
defineFieldActionDivider(),
|
|
1182
|
+
defineAssistFieldAction({/* ... */}),
|
|
1183
|
+
], [])
|
|
1184
|
+
}
|
|
1185
|
+
```
|
|
1186
|
+
|
|
1187
|
+
### `useUserInput`
|
|
1188
|
+
|
|
1189
|
+
<img width="522" alt="user input dialog" src="https://github.com/user-attachments/assets/86966468-9a28-4c0b-99f3-e4b80fdbe691" />
|
|
1190
|
+
|
|
1191
|
+
For certain actions, it is useful to have the user provide additional information or details that can be used
|
|
1192
|
+
as parameters for the action.
|
|
1193
|
+
|
|
1194
|
+
`useUserInput` returns a `getUserInput` function that can be called and awaited to return input from the user.
|
|
1195
|
+
|
|
1196
|
+
The `getUserInput` function takes input configuration and will display an input dialog to the user.
|
|
1197
|
+
When the user completes the dialog, the user inputted text will be available (or undefined if the user closed the dialog).
|
|
1198
|
+
|
|
1199
|
+
|
|
1200
|
+
```ts
|
|
1201
|
+
({
|
|
1202
|
+
fieldActions: {
|
|
1203
|
+
title: 'Custom actions',
|
|
1204
|
+
useFieldActions: (props) => {
|
|
1205
|
+
const getUserInput = useUserInput()
|
|
1206
|
+
|
|
1207
|
+
return useMemo(
|
|
1208
|
+
() => [
|
|
1209
|
+
defineAssistFieldAction({
|
|
1210
|
+
title: 'Do something with user input',
|
|
1211
|
+
onAction: async () => {
|
|
1212
|
+
const inputResult = await getUserInput({
|
|
1213
|
+
title: 'What do you want to do?', // dialog title
|
|
1214
|
+
inputs: [
|
|
1215
|
+
{
|
|
1216
|
+
id: 'topic',
|
|
1217
|
+
title: 'Topic',
|
|
1218
|
+
},
|
|
1219
|
+
{
|
|
1220
|
+
id: 'facts',
|
|
1221
|
+
title: 'Facts',
|
|
1222
|
+
description: 'Provide additional facts that will be used by the action',
|
|
1223
|
+
},
|
|
1224
|
+
],
|
|
1225
|
+
})
|
|
1226
|
+
if (!inputResult) {
|
|
1227
|
+
return // user closed the dialog
|
|
1228
|
+
}
|
|
1229
|
+
|
|
1230
|
+
//use the result from each input
|
|
1231
|
+
//const [{result: topic}, {result: facts}] = inputResult
|
|
1232
|
+
},
|
|
1233
|
+
}),
|
|
1234
|
+
],
|
|
1235
|
+
[getUserInput],
|
|
1236
|
+
)
|
|
1237
|
+
},
|
|
1238
|
+
},
|
|
1239
|
+
})
|
|
1240
|
+
```
|
|
1241
|
+
|
|
943
1242
|
## Caveats
|
|
944
1243
|
|
|
945
1244
|
Large Language Models (LLMs) are a new technology. Constraints and limitations are still being explored,
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
|
+
import {AgentActionPath} from '@sanity/client/stega'
|
|
1
2
|
import {CurrentUser} from 'sanity'
|
|
3
|
+
import {DocumentFieldActionDivider} from 'sanity'
|
|
4
|
+
import {DocumentFieldActionGroup} from 'sanity'
|
|
5
|
+
import {DocumentFieldActionItem} from 'sanity'
|
|
2
6
|
import {JSX as JSX_2} from 'react/jsx-runtime'
|
|
3
7
|
import {ObjectSchemaType} from 'sanity'
|
|
4
8
|
import {Path} from 'sanity'
|
|
@@ -8,7 +12,15 @@ import {PortableTextMarkDefinition} from '@portabletext/types'
|
|
|
8
12
|
import {PortableTextSpan} from '@portabletext/types'
|
|
9
13
|
import {SanityClient} from 'sanity'
|
|
10
14
|
import type {SanityClient as SanityClient_2} from '@sanity/client'
|
|
15
|
+
import {SanityDocumentLike} from 'sanity'
|
|
11
16
|
import {SchemaType} from 'sanity'
|
|
17
|
+
import {SchemaType as SchemaType_2} from '@sanity/types'
|
|
18
|
+
|
|
19
|
+
declare interface AgentActionConditionalPath {
|
|
20
|
+
path: AgentActionPath
|
|
21
|
+
readOnly: boolean
|
|
22
|
+
hidden: boolean
|
|
23
|
+
}
|
|
12
24
|
|
|
13
25
|
export declare const assist: Plugin_2<void | AssistPluginConfig>
|
|
14
26
|
|
|
@@ -62,6 +74,135 @@ export declare interface AssistConfig {
|
|
|
62
74
|
temperature?: number
|
|
63
75
|
}
|
|
64
76
|
|
|
77
|
+
export declare type AssistFieldActionGroup = Omit<
|
|
78
|
+
DocumentFieldActionGroup,
|
|
79
|
+
'renderAsButton' | 'expanded' | 'children'
|
|
80
|
+
> & {
|
|
81
|
+
children: AssistFieldActionNode[]
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
export declare type AssistFieldActionItem = Omit<
|
|
85
|
+
DocumentFieldActionItem,
|
|
86
|
+
'renderAsButton' | 'selected' | 'onAction'
|
|
87
|
+
> & {
|
|
88
|
+
onAction: () => void | Promise<void>
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
export declare type AssistFieldActionNode =
|
|
92
|
+
| AssistFieldActionItem
|
|
93
|
+
| AssistFieldActionGroup
|
|
94
|
+
| DocumentFieldActionDivider
|
|
95
|
+
|
|
96
|
+
export declare interface AssistFieldActionProps {
|
|
97
|
+
/**
|
|
98
|
+
* `actionType` will be `document` for action invoked from the top right document action menu, and
|
|
99
|
+
* `field` when invoked from a field action menu.
|
|
100
|
+
*/
|
|
101
|
+
actionType: 'document' | 'field'
|
|
102
|
+
/**
|
|
103
|
+
* This is the id of the current document pane; it contains `drafts.`or `versions. prefix` ect depending on context.
|
|
104
|
+
* Use this for `documentId` when calling any `client.agent.action`.
|
|
105
|
+
*
|
|
106
|
+
* It is generally recommended to call actions from the studio like this:
|
|
107
|
+
* ```ts
|
|
108
|
+
* await client.agent.action.generate({
|
|
109
|
+
* targetDocument: {
|
|
110
|
+
* operation: 'createIfNotExists',
|
|
111
|
+
* _id: props.documentIdForAction,
|
|
112
|
+
* _type: props.documentSchemaType.name,
|
|
113
|
+
* initialValues: props.getDocumentValue()
|
|
114
|
+
* },
|
|
115
|
+
* //...
|
|
116
|
+
* })
|
|
117
|
+
* ```
|
|
118
|
+
*/
|
|
119
|
+
documentIdForAction: string
|
|
120
|
+
/**
|
|
121
|
+
* Schema type of the current document.
|
|
122
|
+
* @see documentIdForAction
|
|
123
|
+
*/
|
|
124
|
+
documentSchemaType: ObjectSchemaType
|
|
125
|
+
/**
|
|
126
|
+
* Returns the current document value.
|
|
127
|
+
*
|
|
128
|
+
* Prefer passing this function to your hooks instead of passing the document value directly to avoid unnecessary re-renders.
|
|
129
|
+
* @see documentIdForAction
|
|
130
|
+
*/
|
|
131
|
+
getDocumentValue: () => SanityDocumentLike
|
|
132
|
+
/**
|
|
133
|
+
* Returns the current readOnly and hidden state of all conditional members in the current document form.
|
|
134
|
+
*
|
|
135
|
+
* Intended to be passed to agent actions `conditionalPaths.paths`.
|
|
136
|
+
*/
|
|
137
|
+
getConditionalPaths: () => AgentActionConditionalPath[]
|
|
138
|
+
/**
|
|
139
|
+
* `schemaId` for the current workspace.
|
|
140
|
+
*
|
|
141
|
+
* Note: the workspace schema has to be deployed using `sanity schema deploy` or `sanity deploy`.
|
|
142
|
+
*
|
|
143
|
+
* Use this for `schemaId` when calling any `client.agent.action`.
|
|
144
|
+
*
|
|
145
|
+
* It is generally recommended to call actions from the studio like this:
|
|
146
|
+
* ```ts
|
|
147
|
+
* await client.agent.action.generate({
|
|
148
|
+
* targetDocument: {
|
|
149
|
+
* operation: 'createIfNotExists',
|
|
150
|
+
* _id: props.documentIdForAction,
|
|
151
|
+
* _type: props.documentSchemaType.name,
|
|
152
|
+
* initialValues: props.getDocumentValue()
|
|
153
|
+
* },
|
|
154
|
+
* //...
|
|
155
|
+
* })
|
|
156
|
+
*/
|
|
157
|
+
schemaId: string
|
|
158
|
+
/**
|
|
159
|
+
* This is the schema type of the field the actions will be attached to (ie, schemaType for `path`)
|
|
160
|
+
*
|
|
161
|
+
* It can be used with agent actions using `target.path`, to scope the action to a specific field.
|
|
162
|
+
*
|
|
163
|
+
* It is generally recommended to call actions from the studio like this:
|
|
164
|
+
* ```ts
|
|
165
|
+
* await client.agent.action.generate({
|
|
166
|
+
* targetDocument: {
|
|
167
|
+
* operation: 'createIfNotExists',
|
|
168
|
+
* _id: props.documentIdForAction,
|
|
169
|
+
* _type: props.documentSchemaType.name,
|
|
170
|
+
* initialValues: props.getDocumentValue()
|
|
171
|
+
* },
|
|
172
|
+
* target: {
|
|
173
|
+
* path: props.path
|
|
174
|
+
* },
|
|
175
|
+
* })
|
|
176
|
+
* ```
|
|
177
|
+
*/
|
|
178
|
+
path: AgentActionPath
|
|
179
|
+
/**
|
|
180
|
+
* This is the schema type of the field the actions will be attached to (ie, schemaType for `path`).
|
|
181
|
+
*
|
|
182
|
+
* Typically useful to dynamically return different actions based on the schema type of the field.
|
|
183
|
+
*
|
|
184
|
+
* ```ts
|
|
185
|
+
* if(isObjectSchemaType(schemaType)) {
|
|
186
|
+
* return [
|
|
187
|
+
* defineAssistFieldAction({
|
|
188
|
+
* title: 'Fill the object fields',
|
|
189
|
+
* icon: RobotIcon,
|
|
190
|
+
* onAction: () => {
|
|
191
|
+
* //...
|
|
192
|
+
* }
|
|
193
|
+
* })
|
|
194
|
+
* ]
|
|
195
|
+
* }
|
|
196
|
+
* return useMemo(() => {
|
|
197
|
+
*
|
|
198
|
+
*
|
|
199
|
+
* }, [])
|
|
200
|
+
*
|
|
201
|
+
* ```
|
|
202
|
+
*/
|
|
203
|
+
schemaType: SchemaType_2
|
|
204
|
+
}
|
|
205
|
+
|
|
65
206
|
export declare interface AssistOptions {
|
|
66
207
|
aiAssist?: {
|
|
67
208
|
/** Set to true to disable assistance for this field or type */
|
|
@@ -80,6 +221,10 @@ declare interface AssistPluginConfig {
|
|
|
80
221
|
* Config that affects all instructions
|
|
81
222
|
*/
|
|
82
223
|
assist?: AssistConfig
|
|
224
|
+
fieldActions?: {
|
|
225
|
+
title?: string
|
|
226
|
+
useFieldActions?: (props: AssistFieldActionProps) => AssistFieldActionNode[]
|
|
227
|
+
}
|
|
83
228
|
/**
|
|
84
229
|
* @internal
|
|
85
230
|
*/
|
|
@@ -104,6 +249,35 @@ declare interface ContextBlock {
|
|
|
104
249
|
|
|
105
250
|
export declare const contextDocumentTypeName: 'assist.instruction.context'
|
|
106
251
|
|
|
252
|
+
/**
|
|
253
|
+
*
|
|
254
|
+
*/
|
|
255
|
+
export declare interface CustomInput {
|
|
256
|
+
/**
|
|
257
|
+
* Id for the input
|
|
258
|
+
*/
|
|
259
|
+
id: string
|
|
260
|
+
/**
|
|
261
|
+
* Title of the input field
|
|
262
|
+
*/
|
|
263
|
+
title: string
|
|
264
|
+
/**
|
|
265
|
+
* Additional info that will be displayed over the input
|
|
266
|
+
*/
|
|
267
|
+
description?: string
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
export declare type CustomInputResult = {
|
|
271
|
+
/**
|
|
272
|
+
* Identifies which custom input the `result`belongs to
|
|
273
|
+
*/
|
|
274
|
+
input: CustomInput
|
|
275
|
+
/**
|
|
276
|
+
* The text provided by the user in the input
|
|
277
|
+
*/
|
|
278
|
+
result: string
|
|
279
|
+
}
|
|
280
|
+
|
|
107
281
|
/**
|
|
108
282
|
* Default implementation for plugin config `translate.field.translationOutputs`
|
|
109
283
|
*
|
|
@@ -111,6 +285,16 @@ export declare const contextDocumentTypeName: 'assist.instruction.context'
|
|
|
111
285
|
*/
|
|
112
286
|
export declare const defaultLanguageOutputs: TranslationOutputsFunction
|
|
113
287
|
|
|
288
|
+
export declare function defineAssistFieldAction(
|
|
289
|
+
action: Omit<AssistFieldActionItem, 'type'>,
|
|
290
|
+
): AssistFieldActionItem
|
|
291
|
+
|
|
292
|
+
export declare function defineAssistFieldActionGroup(
|
|
293
|
+
group: Omit<AssistFieldActionGroup, 'type'>,
|
|
294
|
+
): AssistFieldActionGroup
|
|
295
|
+
|
|
296
|
+
export declare function defineFieldActionDivider(): DocumentFieldActionDivider
|
|
297
|
+
|
|
114
298
|
export declare interface DocumentMember {
|
|
115
299
|
schemaType: SchemaType
|
|
116
300
|
path: Path
|
|
@@ -252,10 +436,29 @@ export declare interface FieldTranslationConfig {
|
|
|
252
436
|
maxPathDepth?: number
|
|
253
437
|
}
|
|
254
438
|
|
|
439
|
+
export declare type GetUserInput = (args: {
|
|
440
|
+
/**
|
|
441
|
+
* Dialog title
|
|
442
|
+
*/
|
|
443
|
+
title: string
|
|
444
|
+
/**
|
|
445
|
+
* One titled input per array item
|
|
446
|
+
*/
|
|
447
|
+
inputs: CustomInput[]
|
|
448
|
+
}) => Promise<CustomInputResult[] | undefined>
|
|
449
|
+
|
|
255
450
|
declare type InlinePromptBlock = PortableTextSpan | FieldRef | UserInputBlock | ContextBlock
|
|
256
451
|
|
|
257
452
|
declare const instructionContextTypeName: 'sanity.assist.instruction.context'
|
|
258
453
|
|
|
454
|
+
/**
|
|
455
|
+
* Returns true if the `schemaType` or any of its parent types (`schemaType.type`)` has `name` equal
|
|
456
|
+
* to `typeName`.
|
|
457
|
+
*
|
|
458
|
+
* Useful for checking if `schemaType` is a type alias of `ìmage`, `code` or similar.
|
|
459
|
+
*/
|
|
460
|
+
export declare function isType(schemaType: SchemaType, typeName: string): boolean
|
|
461
|
+
|
|
259
462
|
export declare interface Language {
|
|
260
463
|
id: string
|
|
261
464
|
title?: string
|
|
@@ -395,6 +598,68 @@ declare interface UserInputBlock {
|
|
|
395
598
|
|
|
396
599
|
declare const userInputTypeName: 'sanity.assist.instruction.userInput'
|
|
397
600
|
|
|
601
|
+
/**
|
|
602
|
+
* `useUserInput` returns a function that can be used to await user input.
|
|
603
|
+
*
|
|
604
|
+
* Useful for custom `fieldActions` to get user input for populating Agent Action requests,.
|
|
605
|
+
*
|
|
606
|
+
* ```ts
|
|
607
|
+
* fieldActions: {
|
|
608
|
+
* useFieldActions: (props) => {
|
|
609
|
+
* const {
|
|
610
|
+
* documentSchemaType,
|
|
611
|
+
* schemaId,
|
|
612
|
+
* getDocumentValue,
|
|
613
|
+
* getConditionalPaths,
|
|
614
|
+
* documentIdForAction,
|
|
615
|
+
* } = props
|
|
616
|
+
* const client = useClient({apiVersion: 'vX'})
|
|
617
|
+
* const getUserInput = useUserInput()
|
|
618
|
+
* return useMemo(() => {
|
|
619
|
+
* return [
|
|
620
|
+
* defineAssistFieldAction({
|
|
621
|
+
* title: 'Log user input',
|
|
622
|
+
* icon: UserIcon,
|
|
623
|
+
* onAction: async () => {
|
|
624
|
+
* const input = await getUserInput({
|
|
625
|
+
* title: 'Topic',
|
|
626
|
+
* inputs: [{id: 'about', title: 'What should the article be about?'}],
|
|
627
|
+
* })
|
|
628
|
+
* if (!input) return // user canceled input
|
|
629
|
+
* await client.agent.action.generate({
|
|
630
|
+
* schemaId,
|
|
631
|
+
* targetDocument: {
|
|
632
|
+
* operation: 'createIfNotExists',
|
|
633
|
+
* _id: documentIdForAction,
|
|
634
|
+
* _type: documentSchemaType.name,
|
|
635
|
+
* initialValues: getDocumentValue(),
|
|
636
|
+
* },
|
|
637
|
+
* instruction: `
|
|
638
|
+
* Create a document about the following topic:
|
|
639
|
+
* $about
|
|
640
|
+
* ---
|
|
641
|
+
* `,
|
|
642
|
+
* instructionParams: {about: input[0].result},
|
|
643
|
+
* conditionalPaths: {paths: getConditionalPaths()},
|
|
644
|
+
* })
|
|
645
|
+
* },
|
|
646
|
+
* }),
|
|
647
|
+
* ]
|
|
648
|
+
* }, [
|
|
649
|
+
* client,
|
|
650
|
+
* documentSchemaType,
|
|
651
|
+
* schemaId,
|
|
652
|
+
* getDocumentValue,
|
|
653
|
+
* getConditionalPaths,
|
|
654
|
+
* documentIdForAction,
|
|
655
|
+
* getUserInput,
|
|
656
|
+
* ])
|
|
657
|
+
* },
|
|
658
|
+
* }
|
|
659
|
+
* ```
|
|
660
|
+
*/
|
|
661
|
+
export declare function useUserInput(): GetUserInput
|
|
662
|
+
|
|
398
663
|
export {}
|
|
399
664
|
|
|
400
665
|
declare module 'sanity' {
|