@sanity/client 7.1.0 → 7.2.1-agent-actions.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,6 +3,7 @@ import {lastValueFrom, type Observable} from 'rxjs'
3
3
  import type {ObservableSanityClient, SanityClient} from '../../SanityClient'
4
4
  import type {Any, HttpRequest, IdentifiedSanityDocumentStub, TranslateDocument} from '../../types'
5
5
  import {_generate, type GenerateInstruction} from './generate'
6
+ import {_prompt, type PromptRequest} from './prompt'
6
7
  import {_transform, type TransformDocument} from './transform'
7
8
  import {_translate} from './translate'
8
9
 
@@ -108,4 +109,14 @@ export class AgentActionsClient {
108
109
  > {
109
110
  return lastValueFrom(_translate(this.#client, this.#httpRequest, request))
110
111
  }
112
+
113
+ /**
114
+ * Run a raw instruction and return the result either as text or json
115
+ * @param request - prompt request
116
+ */
117
+ prompt<DocumentShape extends Record<string, Any>>(
118
+ request: PromptRequest<DocumentShape>,
119
+ ): Promise<(typeof request)['json'] extends true ? DocumentShape : string> {
120
+ return lastValueFrom(_prompt(this.#client, this.#httpRequest, request))
121
+ }
111
122
  }
@@ -35,6 +35,16 @@ export interface ConstantAgentActionParam {
35
35
  value: string
36
36
  }
37
37
 
38
+ type DocIdParam<TParamConfig extends {docIdRequired: boolean} = {docIdRequired: false}> =
39
+ TParamConfig['docIdRequired'] extends true
40
+ ? {documentId: string}
41
+ : {
42
+ /**
43
+ * If omitted, implicitly uses the documentId of the instruction target
44
+ */
45
+ documentId?: string
46
+ }
47
+
38
48
  /**
39
49
  *
40
50
  *
@@ -58,17 +68,15 @@ export interface ConstantAgentActionParam {
58
68
  *
59
69
  * @beta
60
70
  * */
61
- export interface FieldAgentActionParam {
71
+ export type FieldAgentActionParam<
72
+ TParamConfig extends {docIdRequired: boolean} = {docIdRequired: false},
73
+ > = {
62
74
  type: 'field'
63
75
  /**
64
76
  * Examples: 'title', ['array', \{_key: 'arrayItemKey'\}, 'field']
65
77
  */
66
78
  path: AgentActionPathSegment | AgentActionPath
67
- /**
68
- * If omitted, implicitly uses the documentId of the instruction target
69
- */
70
- documentId?: string
71
- }
79
+ } & DocIdParam<TParamConfig>
72
80
 
73
81
  /**
74
82
  *
@@ -90,13 +98,11 @@ export interface FieldAgentActionParam {
90
98
  *
91
99
  * @beta
92
100
  * */
93
- export interface DocumentAgentActionParam {
101
+ export type DocumentAgentActionParam<
102
+ TParamConfig extends {docIdRequired: boolean} = {docIdRequired: false},
103
+ > = {
94
104
  type: 'document'
95
- /**
96
- * If omitted, implicitly uses the documentId of the instruction target
97
- */
98
- documentId?: string
99
- }
105
+ } & DocIdParam<TParamConfig>
100
106
 
101
107
  /**
102
108
  * Includes a LLM-friendly version of GROQ query result in the instruction
@@ -209,15 +215,19 @@ export interface AgentActionTarget {
209
215
  }
210
216
 
211
217
  /** @beta */
212
- export type AgentActionParam =
218
+ export type AgentActionParam<
219
+ TParamConfig extends {docIdRequired: boolean} = {docIdRequired: false},
220
+ > =
213
221
  | string
214
222
  | ConstantAgentActionParam
215
- | FieldAgentActionParam
216
- | DocumentAgentActionParam
223
+ | FieldAgentActionParam<TParamConfig>
224
+ | DocumentAgentActionParam<TParamConfig>
217
225
  | GroqAgentActionParam
218
226
 
219
227
  /** @beta */
220
- export type AgentActionParams = Record<string, AgentActionParam>
228
+ export type AgentActionParams<
229
+ TParamConfig extends {docIdRequired: boolean} = {docIdRequired: false},
230
+ > = Record<string, AgentActionParam<TParamConfig>>
221
231
 
222
232
  /** @beta */
223
233
  export interface AgentActionRequestBase {
@@ -0,0 +1,150 @@
1
+ import {type Observable} from 'rxjs'
2
+
3
+ import {_request} from '../../data/dataMethods'
4
+ import type {ObservableSanityClient, SanityClient} from '../../SanityClient'
5
+ import type {AgentActionParams, Any, HttpRequest} from '../../types'
6
+ import {hasDataset} from '../../validators'
7
+
8
+ /** @beta */
9
+ export interface PromptRequestBase {
10
+ /**
11
+ * Instruct the LLM how it should generate content. Be as specific and detailed as needed.
12
+ *
13
+ * The LLM only has access to information in the instruction, plus the target schema.
14
+ *
15
+ * string template using $variable
16
+ * */
17
+ instruction: string
18
+ /**
19
+ * param values for the string template, keys are the variable name, ie if the template has "$variable", one key must be "variable"
20
+ *
21
+ * ### Examples
22
+ *
23
+ * #### Constant
24
+ *
25
+ * ##### Shorthand
26
+ * ```ts
27
+ * client.agent.action.generate({
28
+ * schemaId,
29
+ * documentId,
30
+ * instruction: 'Give the following topic:\n $topic \n ---\nReturns some facts about it',
31
+ * instructionParams: {
32
+ * topic: 'Grapefruit'
33
+ * },
34
+ * })
35
+ * ```
36
+ * ##### Object-form
37
+ *
38
+ * ```ts
39
+ * client.agent.action.prompt({
40
+ * instruction: 'Give the following topic:\n $topic \n ---\nReturns some facts about it.',
41
+ * instructionParams: {
42
+ * topic: {
43
+ * type: 'constant',
44
+ * value: 'Grapefruit'
45
+ * },
46
+ * },
47
+ * })
48
+ * ```
49
+ * #### Field
50
+ * ```ts
51
+ * client.agent.action.prompt({
52
+ * instruction: 'Give the following field value:\n $pte \n ---\nGenerate keywords.',
53
+ * instructionParams: {
54
+ * pte: {
55
+ * type: 'field',
56
+ * path: ['pteField'],
57
+ * documentId: 'someSanityDocId'
58
+ * },
59
+ * },
60
+ * })
61
+ * ```
62
+ * #### Document
63
+ * ```ts
64
+ * client.agent.action.prompt({
65
+ * json: true,
66
+ * instruction: 'Given the following document:$document\nCreate a JSON string[] array with keywords describing it.',
67
+ * instructionParams: {
68
+ * document: {
69
+ * type: 'document',
70
+ * documentId: 'someSanityDocId'
71
+ * },
72
+ * },
73
+ * })
74
+ * ```
75
+ *
76
+ * #### GROQ
77
+ * ```ts
78
+ * client.agent.action.prompt({
79
+ * instruction: 'Return the best title amongst these: $titles.',
80
+ * instructionParams: {
81
+ * titles: {
82
+ * type: 'groq',
83
+ * query: '* [_type==$type].title',
84
+ * params: {type: 'article'}
85
+ * },
86
+ * },
87
+ * })
88
+ * ```
89
+ * */
90
+ instructionParams?: AgentActionParams<{docIdRequired: true}>
91
+
92
+ /**
93
+ * Controls how much variance the instructions will run with.
94
+ *
95
+ * Value must be in the range [0, 1] (inclusive).
96
+ *
97
+ * Defaults:
98
+ * - generate: 0.3
99
+ * - translate: 0
100
+ * - transform: 0
101
+ */
102
+ temperature?: number
103
+ }
104
+
105
+ /**
106
+ * @beta
107
+ */
108
+ // need the unused generic here to allow for optional callsite casting
109
+ // eslint-disable-next-line unused-imports/no-unused-vars
110
+ interface PromptJsonResponse<T extends Record<string, Any> = Record<string, Any>> {
111
+ /**
112
+ *
113
+ * When true, the response body will be json according to the instruction.
114
+ * When false, the response is the raw text response to the instruction.
115
+ *
116
+ * Note: In addition to setting this to true, `instruction` MUST include the word 'JSON', or 'json' for this to work.
117
+ */
118
+ json: true
119
+ }
120
+
121
+ interface PromptTextResponse {
122
+ /**
123
+ *
124
+ * When true, the response body will be json according to the instruction.
125
+ * When false, the response is the raw text response to the instruction.
126
+ *
127
+ * Note: In addition to setting this to true, `instruction` MUST include the word 'JSON', or 'json' for this to work.
128
+ */
129
+ json?: false
130
+ }
131
+
132
+ /** @beta */
133
+ export type PromptRequest<T extends Record<string, Any> = Record<string, Any>> = (
134
+ | PromptTextResponse
135
+ | PromptJsonResponse<T>
136
+ ) &
137
+ PromptRequestBase
138
+
139
+ export function _prompt<DocumentShape extends Record<string, Any>>(
140
+ client: SanityClient | ObservableSanityClient,
141
+ httpRequest: HttpRequest,
142
+ request: PromptRequest<DocumentShape>,
143
+ ): Observable<(typeof request)['json'] extends true ? DocumentShape : string> {
144
+ const dataset = hasDataset(client.config())
145
+ return _request(client, httpRequest, {
146
+ method: 'POST',
147
+ uri: `/agent/action/prompt/${dataset}`,
148
+ body: request,
149
+ })
150
+ }
@@ -1,3 +1,4 @@
1
+ import {getVersionFromId, getVersionId, isDraftId} from '@sanity/client/csm'
1
2
  import {from, type MonoTypeOperatorFunction, Observable} from 'rxjs'
2
3
  import {combineLatestWith, filter, map} from 'rxjs/operators'
3
4
 
@@ -12,6 +13,8 @@ import type {
12
13
  Any,
13
14
  BaseActionOptions,
14
15
  BaseMutationOptions,
16
+ CreateVersionAction,
17
+ DiscardVersionAction,
15
18
  FirstDocumentIdMutationOptions,
16
19
  FirstDocumentMutationOptions,
17
20
  HttpRequest,
@@ -25,11 +28,13 @@ import type {
25
28
  MutationSelection,
26
29
  QueryOptions,
27
30
  RawQueryResponse,
31
+ ReplaceVersionAction,
28
32
  RequestObservableOptions,
29
33
  RequestOptions,
30
34
  SanityDocument,
31
35
  SingleActionResult,
32
36
  SingleMutationResult,
37
+ UnpublishVersionAction,
33
38
  } from '../types'
34
39
  import {getSelection} from '../util/getSelection'
35
40
  import * as validate from '../validators'
@@ -132,10 +137,36 @@ export function _getDocument<R extends Record<string, Any>>(
132
137
  client: Client,
133
138
  httpRequest: HttpRequest,
134
139
  id: string,
135
- opts: {signal?: AbortSignal; tag?: string} = {},
140
+ opts: {signal?: AbortSignal; tag?: string; releaseId?: string} = {},
136
141
  ): Observable<SanityDocument<R> | undefined> {
142
+ const getDocId = () => {
143
+ if (!opts.releaseId) {
144
+ return id
145
+ }
146
+
147
+ const versionId = getVersionFromId(id)
148
+ if (!versionId) {
149
+ if (isDraftId(id)) {
150
+ throw new Error(
151
+ `The document ID (\`${id}\`) is a draft, but \`options.releaseId\` is set as \`${opts.releaseId}\``,
152
+ )
153
+ }
154
+
155
+ return getVersionId(id, opts.releaseId)
156
+ }
157
+
158
+ if (versionId !== opts.releaseId) {
159
+ throw new Error(
160
+ `The document ID (\`${id}\`) is already a version of \`${versionId}\` release, but this does not match the provided \`options.releaseId\` (\`${opts.releaseId}\`)`,
161
+ )
162
+ }
163
+
164
+ return id
165
+ }
166
+ const docId = getDocId()
167
+
137
168
  const options = {
138
- uri: _getDataUrl(client, 'doc', id),
169
+ uri: _getDataUrl(client, 'doc', docId),
139
170
  json: true,
140
171
  tag: opts.tag,
141
172
  signal: opts.signal,
@@ -168,6 +199,27 @@ export function _getDocuments<R extends Record<string, Any>>(
168
199
  )
169
200
  }
170
201
 
202
+ /** @internal */
203
+ export function _getReleaseDocuments<R extends Record<string, Any>>(
204
+ client: ObservableSanityClient | SanityClient,
205
+ httpRequest: HttpRequest,
206
+ releaseId: string,
207
+ opts: BaseMutationOptions = {},
208
+ ): Observable<RawQueryResponse<SanityDocument<R>[]>> {
209
+ return _dataRequest(
210
+ client,
211
+ httpRequest,
212
+ 'query',
213
+ {
214
+ query: '*[sanity::partOfRelease($releaseId)]',
215
+ params: {
216
+ releaseId,
217
+ },
218
+ },
219
+ opts,
220
+ )
221
+ }
222
+
171
223
  /** @internal */
172
224
  export function _createIfNotExists<R extends Record<string, Any>>(
173
225
  client: Client,
@@ -204,6 +256,26 @@ export function _createOrReplace<R extends Record<string, Any>>(
204
256
  return _create<R>(client, httpRequest, doc, 'createOrReplace', options)
205
257
  }
206
258
 
259
+ /** @internal */
260
+ export function _createVersion<R extends Record<string, Any>>(
261
+ client: ObservableSanityClient | SanityClient,
262
+ httpRequest: HttpRequest,
263
+ doc: IdentifiedSanityDocumentStub<R>,
264
+ publishedId: string,
265
+ options?: BaseActionOptions,
266
+ ): Observable<SingleActionResult> {
267
+ validators.requireDocumentId('createVersion', doc)
268
+ validators.requireDocumentType('createVersion', doc)
269
+
270
+ const createVersionAction: CreateVersionAction = {
271
+ actionType: 'sanity.action.document.version.create',
272
+ publishedId,
273
+ document: doc,
274
+ }
275
+
276
+ return _action(client, httpRequest, createVersionAction, options)
277
+ }
278
+
207
279
  /** @internal */
208
280
  export function _delete<R extends Record<string, Any>>(
209
281
  client: Client,
@@ -227,6 +299,58 @@ export function _delete<R extends Record<string, Any>>(
227
299
  )
228
300
  }
229
301
 
302
+ /** @internal */
303
+ export function _discardVersion(
304
+ client: ObservableSanityClient | SanityClient,
305
+ httpRequest: HttpRequest,
306
+ versionId: string,
307
+ purge: boolean = false,
308
+ options?: BaseActionOptions,
309
+ ): Observable<SingleActionResult> {
310
+ const discardVersionAction: DiscardVersionAction = {
311
+ actionType: 'sanity.action.document.version.discard',
312
+ versionId,
313
+ purge,
314
+ }
315
+
316
+ return _action(client, httpRequest, discardVersionAction, options)
317
+ }
318
+
319
+ /** @internal */
320
+ export function _replaceVersion<R extends Record<string, Any>>(
321
+ client: ObservableSanityClient | SanityClient,
322
+ httpRequest: HttpRequest,
323
+ doc: IdentifiedSanityDocumentStub<R>,
324
+ options?: BaseActionOptions,
325
+ ): Observable<SingleActionResult> {
326
+ validators.requireDocumentId('replaceVersion', doc)
327
+ validators.requireDocumentType('replaceVersion', doc)
328
+
329
+ const replaceVersionAction: ReplaceVersionAction = {
330
+ actionType: 'sanity.action.document.version.replace',
331
+ document: doc,
332
+ }
333
+
334
+ return _action(client, httpRequest, replaceVersionAction, options)
335
+ }
336
+
337
+ /** @internal */
338
+ export function _unpublishVersion(
339
+ client: ObservableSanityClient | SanityClient,
340
+ httpRequest: HttpRequest,
341
+ versionId: string,
342
+ publishedId: string,
343
+ options?: BaseActionOptions,
344
+ ): Observable<SingleActionResult> {
345
+ const unpublishVersionAction: UnpublishVersionAction = {
346
+ actionType: 'sanity.action.document.version.unpublish',
347
+ versionId,
348
+ publishedId,
349
+ }
350
+
351
+ return _action(client, httpRequest, unpublishVersionAction, options)
352
+ }
353
+
230
354
  /** @internal */
231
355
  export function _mutate<R extends Record<string, Any>>(
232
356
  client: Client,