sanity-plugin-jev-fields 0.1.0 → 0.2.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.
- package/README.md +110 -41
- package/dist/index.d.ts +25 -25
- package/dist/index.js +127 -127
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,30 +2,43 @@
|
|
|
2
2
|
|
|
3
3
|
> Beta: expect `0.x` releases to change until the stored value shapes are frozen at `1.0.0`.
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
5
|
+
Editorial checks that run while editors write. Ask a question about a field ("Is this easy to
|
|
6
|
+
read?", "How well are the claims backed up?") and the answer shows up under the field, is stored
|
|
7
|
+
next to it for you to query, and can warn or block publishing.
|
|
8
|
+
|
|
9
|
+
The questions are answered by [TypeSafe's Jev](https://typesafe.ai), a decision model that
|
|
10
|
+
answers a question with a probability instead of writing text, through
|
|
11
|
+
[Vercel AI Gateway](https://vercel.com/ai-gateway). Each question shows as a chip under the field
|
|
12
|
+
it judges; click it for the details. There are three kinds:
|
|
9
13
|
|
|
10
14
|
- `noul`: a yes/no question, answered with the probability that the answer is yes
|
|
11
15
|
- `score`: a position on an ordered scale you define
|
|
12
16
|
- `choice`: one option from a named set, with a probability for each option
|
|
13
17
|
|
|
14
|
-
|
|
18
|
+
Questions are re-evaluated shortly after the field is edited. Opening a document never writes to it.
|
|
15
19
|
|
|
16
|
-
|
|
20
|
+
<img src="https://raw.githubusercontent.com/frederikvonsperling/sanity-plugin-jev-fields/main/docs/images/readable.png" width="612" alt="A Body field in Sanity Studio with three question chips under it: Readable 90%, Evidence 1.5/3 and Tone Casual. The Readable details are open: a High badge, 90% likely to read easily, a nearly full green bar, and the hint "Short sentences, plain words, clear structure".">
|
|
17
21
|
|
|
18
22
|
## Install
|
|
19
23
|
|
|
24
|
+
```sh
|
|
25
|
+
npm install sanity-plugin-jev-fields
|
|
26
|
+
```
|
|
27
|
+
|
|
20
28
|
```sh
|
|
21
29
|
pnpm add sanity-plugin-jev-fields
|
|
22
30
|
```
|
|
23
31
|
|
|
24
|
-
|
|
32
|
+
```sh
|
|
33
|
+
yarn add sanity-plugin-jev-fields
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Requires Sanity Studio 6. Its peer dependencies, `react` and `react-dom` 19.2 or later and
|
|
37
|
+
`styled-components` 6.1 or later, come with any Studio 6 project.
|
|
25
38
|
|
|
26
39
|
## Usage
|
|
27
40
|
|
|
28
|
-
Add the plugin, and wrap your schema types with `withJevAnswers` so every
|
|
41
|
+
Add the plugin, and wrap your schema types with `withJevAnswers` so every question gets a field to
|
|
29
42
|
store its answer in:
|
|
30
43
|
|
|
31
44
|
```ts
|
|
@@ -40,7 +53,7 @@ export default defineConfig({
|
|
|
40
53
|
})
|
|
41
54
|
```
|
|
42
55
|
|
|
43
|
-
Then attach
|
|
56
|
+
Then attach questions to any field with `options.jev`:
|
|
44
57
|
|
|
45
58
|
```ts
|
|
46
59
|
import {defineArrayMember, defineField} from 'sanity'
|
|
@@ -70,41 +83,54 @@ defineField({
|
|
|
70
83
|
}),
|
|
71
84
|
tone: choice({
|
|
72
85
|
instructions: 'What is the tone of this article?',
|
|
73
|
-
criteria: {
|
|
86
|
+
criteria: {
|
|
87
|
+
formal: 'Professional and reserved',
|
|
88
|
+
casual: 'Conversational and relaxed',
|
|
89
|
+
playful: 'Light-hearted and witty',
|
|
90
|
+
},
|
|
74
91
|
}),
|
|
75
92
|
},
|
|
76
93
|
},
|
|
77
94
|
})
|
|
78
95
|
```
|
|
79
96
|
|
|
80
|
-
A
|
|
97
|
+
A question reads only the field it is attached to. Portable Text, slugs and nested objects are
|
|
81
98
|
flattened to plain text. Each key (`readable`, `evidence`, `tone`) becomes the name of a field
|
|
82
99
|
next to it that stores the answer; `withJevAnswers` adds those fields and stops with an error if a
|
|
83
|
-
name is already taken.
|
|
100
|
+
name is already taken. A `score` takes 2 to 10 criteria and a `choice` 2 to 255 options; see
|
|
101
|
+
[Question options](#question-options) for the rest.
|
|
102
|
+
|
|
103
|
+
<img src="https://raw.githubusercontent.com/frederikvonsperling/sanity-plugin-jev-fields/main/docs/images/tone.png" width="612" alt="A Title field with a Tone Casual chip under it. The Tone details are open: bars for Formal 3%, Casual 97% and Playful 0%, the meaning "Conversational and relaxed", and the note "Out of date: the field changed since this was evaluated."">
|
|
104
|
+
|
|
105
|
+
When a field changes, its answers are marked out of date until they are evaluated again.
|
|
84
106
|
|
|
85
107
|
## Rules
|
|
86
108
|
|
|
87
|
-
Give a
|
|
109
|
+
Give a question a `warn` or `require` rule to act on its answer: `warn` shows a warning on the
|
|
88
110
|
attached field, `require` an error that blocks publishing.
|
|
89
111
|
|
|
90
112
|
```ts
|
|
91
113
|
options: {
|
|
92
114
|
jev: {
|
|
93
|
-
readable: noul({...
|
|
94
|
-
evidence: score({...
|
|
95
|
-
|
|
115
|
+
readable: noul({...question, warn: {atLeast: 0.6}}), // probability, 0–1
|
|
116
|
+
evidence: score({...question, require: {atLeast: 2}}), // position on the scale
|
|
117
|
+
risk: score({...question, colors: 'reverse', warn: {atMost: 1}}), // lower is better
|
|
118
|
+
tone: choice({...question, warn: {oneOf: ['formal', 'casual']}}),
|
|
96
119
|
},
|
|
97
120
|
}
|
|
98
121
|
```
|
|
99
122
|
|
|
100
|
-
|
|
123
|
+
`noul` and `score` rules take `atLeast`, `atMost` or both. `choice` rules take `oneOf`, the options
|
|
124
|
+
the answer must be one of.
|
|
125
|
+
|
|
126
|
+
Rules judge the stored answer, so they say nothing until a question has been evaluated, and an
|
|
101
127
|
answer that is out of date is still judged as it is.
|
|
102
128
|
|
|
103
129
|
## What Jev is good at
|
|
104
130
|
|
|
105
131
|
Jev judges meaning in text: tone, clarity, whether claims are backed up. It reads only text, so
|
|
106
132
|
images and other media in a field are ignored. It is not built for counting or arithmetic: ask
|
|
107
|
-
"Is this under 150 words?" in a validation rule instead. Test
|
|
133
|
+
"Is this under 150 words?" in a validation rule instead. Test questions on content in your own
|
|
108
134
|
languages before relying on them. A field's text may be up to about 32k tokens; the Studio warns
|
|
109
135
|
when a field gets close.
|
|
110
136
|
|
|
@@ -113,36 +139,51 @@ when a field gets close.
|
|
|
113
139
|
Open the **Jev** tool in the Studio, click **Set key** and paste an AI Gateway API key. The tool
|
|
114
140
|
shows whether a key is set, when it last changed, and can test the connection.
|
|
115
141
|
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
access, such as a frontend's read or preview token. It is also
|
|
119
|
-
backups. Use a dedicated key with a spend limit.
|
|
142
|
+
> **Anyone who can read the dataset can read the key.** It is stored in the document
|
|
143
|
+
> `secrets.jev`. Unauthenticated queries can't read it, but every Studio user can, and so can
|
|
144
|
+
> every API token with read access, such as a frontend's read or preview token. It is also
|
|
145
|
+
> included in dataset exports and backups. Use a dedicated key with a spend limit.
|
|
146
|
+
|
|
147
|
+
You can also pass the key as the plugin's `apiKey` option, but then it is bundled into the
|
|
148
|
+
Studio's JavaScript, where anyone who can load the Studio can read it.
|
|
120
149
|
|
|
121
150
|
If editors and tokens must never see the key, send requests through your own server instead:
|
|
122
151
|
|
|
123
152
|
```ts
|
|
124
153
|
jev({
|
|
125
154
|
transport: (request, {signal}) =>
|
|
126
|
-
fetch('/api/jev', {
|
|
155
|
+
fetch('/api/jev', {
|
|
156
|
+
method: 'POST',
|
|
157
|
+
headers: {'Content-Type': 'application/json'},
|
|
158
|
+
body: JSON.stringify(request),
|
|
159
|
+
signal,
|
|
160
|
+
}),
|
|
127
161
|
})
|
|
128
162
|
```
|
|
129
163
|
|
|
130
164
|
Your endpoint forwards the body unchanged to `https://ai-gateway.vercel.sh/v1/evaluate` with an
|
|
131
|
-
`Authorization: Bearer <key>` header
|
|
165
|
+
`Authorization: Bearer <key>` header and a `Content-Type: application/json` header, and returns
|
|
166
|
+
the Gateway's response with its status.
|
|
167
|
+
|
|
168
|
+
When more than one is set, `transport` wins over `apiKey`, and `apiKey` over the stored key.
|
|
132
169
|
|
|
133
170
|
## Stored values
|
|
134
171
|
|
|
135
172
|
```groq
|
|
136
173
|
*[_type == "article"]{
|
|
137
174
|
title,
|
|
138
|
-
|
|
139
|
-
"
|
|
140
|
-
|
|
175
|
+
// noul: probability that the answer is yes, 0–1
|
|
176
|
+
"readable": readable.probability,
|
|
177
|
+
// score: score runs from 0 to max; label is the nearest criterion; confidence is 0–1
|
|
178
|
+
"evidence": evidence{score, max, label, confidence},
|
|
179
|
+
// choice: the chosen option, confidence 0–1, and a probability for every option
|
|
180
|
+
"tone": tone{choice, confidence, probabilities[]{option, probability}}
|
|
141
181
|
}
|
|
142
182
|
```
|
|
143
183
|
|
|
144
184
|
Every value also stores `evaluatedAt`, `model` (e.g. `typesafe-ai/jev`) and a `sourceHash` the
|
|
145
|
-
Studio uses to show when a value is out of date.
|
|
185
|
+
Studio uses to show when a value is out of date. The types `NoulValue`, `ScoreValue` and
|
|
186
|
+
`ChoiceValue` describe the full shapes.
|
|
146
187
|
|
|
147
188
|
## Translations
|
|
148
189
|
|
|
@@ -163,22 +204,50 @@ export const jevNorwegian = defineLocaleResourceBundle({
|
|
|
163
204
|
Rule messages and config problems stay in English: Sanity's validation has no translation hook,
|
|
164
205
|
and config problems are meant for schema authors.
|
|
165
206
|
|
|
166
|
-
##
|
|
207
|
+
## Options reference
|
|
167
208
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
209
|
+
### Plugin options
|
|
210
|
+
|
|
211
|
+
Passed to `jev({...})`. All are optional.
|
|
212
|
+
|
|
213
|
+
| Option | Default | Description |
|
|
214
|
+
| ------------ | ------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------- |
|
|
215
|
+
| `transport` | | `(request, {signal}) => Promise<Response>`. Sends requests yourself, e.g. through your own server. See [API key](#api-key). |
|
|
216
|
+
| `apiKey` | | AI Gateway key. Bundled into the Studio's JavaScript; prefer the Jev tool or `transport`. |
|
|
217
|
+
| `endpoint` | `https://ai-gateway.vercel.sh/v1/evaluate` | Where requests go. Ignored when `transport` is set. |
|
|
218
|
+
| `model` | `typesafe-ai/jev` | Decision model to call. |
|
|
219
|
+
| `debounceMs` | `500` | Delay after the last edit before re-evaluating, in milliseconds. |
|
|
220
|
+
| `tool` | `true` | Adds the Jev tool for setting, testing and removing the stored key. |
|
|
221
|
+
| `tags` | `['feature:jev-fields']` | AI Gateway reporting tags, for cost attribution. Each request also gets a tag for its question, e.g. `jev.noul:article.readable`. |
|
|
222
|
+
|
|
223
|
+
### Question options
|
|
224
|
+
|
|
225
|
+
Every question takes:
|
|
226
|
+
|
|
227
|
+
| Option | Description |
|
|
228
|
+
| -------------- | ----------------------------------------------------------------------------------- |
|
|
229
|
+
| `instructions` | Required. The question Jev answers about the attached field. |
|
|
230
|
+
| `title` | Chip and detail heading. Defaults to the question's key: `readable` → "Readable". |
|
|
231
|
+
| `warn` | Shows a warning on the field when the answer breaks this rule. See [Rules](#rules). |
|
|
232
|
+
| `require` | Blocks publishing when the answer breaks this rule. |
|
|
233
|
+
|
|
234
|
+
And, per kind:
|
|
235
|
+
|
|
236
|
+
| Kind | Option | Description |
|
|
237
|
+
| -------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
238
|
+
| `noul` | `true` | Required. What a yes means. Shown when the probability is 50% or higher. |
|
|
239
|
+
| `noul` | `false` | Required. What a no means. Shown when the probability is below 50%. |
|
|
240
|
+
| `noul` | `label` | Short phrase after the percentage, e.g. "likely to read easily". |
|
|
241
|
+
| `score` | `criteria` | Required. 2 to 10 criteria, lowest first. Text before a colon is the short label. |
|
|
242
|
+
| `score` | `colors` | `'traffic'` (default): red at the bottom, green at the top. `'reverse'`: green at the bottom, for scales where lower is better. `'neutral'`: one colour throughout. |
|
|
243
|
+
| `choice` | `criteria` | Required. 2 to 255 options, as option name → what it means. |
|
|
244
|
+
|
|
245
|
+
Rules on a `noul` take probabilities (0–1), rules on a `score` take positions on the scale (0 to
|
|
246
|
+
the number of criteria minus one), and rules on a `choice` take option names.
|
|
173
247
|
|
|
174
|
-
|
|
175
|
-
`AI_GATEWAY_API_KEY` in `.env`). [CONTEXT.md](./CONTEXT.md) defines the vocabulary and
|
|
176
|
-
[docs/adr](./docs/adr) records the main decisions.
|
|
248
|
+
## Contributing
|
|
177
249
|
|
|
178
|
-
|
|
179
|
-
"Version packages" PR up to date; merging it stages the new version on npm (trusted publishing,
|
|
180
|
-
no token) and creates the GitHub release. A maintainer then approves the staged version on
|
|
181
|
-
npmjs.com, with 2FA, to publish it.
|
|
250
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md).
|
|
182
251
|
|
|
183
252
|
## License
|
|
184
253
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { SchemaTypeDefinition } from "sanity";
|
|
2
2
|
import "react";
|
|
3
3
|
/** @public */
|
|
4
|
-
type
|
|
4
|
+
type GatewayQuestion = {
|
|
5
5
|
type: 'boolean';
|
|
6
6
|
instructions: string;
|
|
7
7
|
criteria: {
|
|
@@ -18,7 +18,7 @@ type JevQuestion = {
|
|
|
18
18
|
criteria: Record<string, string>;
|
|
19
19
|
};
|
|
20
20
|
/** @public */
|
|
21
|
-
type
|
|
21
|
+
type GatewayAnswer = {
|
|
22
22
|
type: 'boolean';
|
|
23
23
|
probability: number;
|
|
24
24
|
} | {
|
|
@@ -41,7 +41,7 @@ interface JevRequest {
|
|
|
41
41
|
model: string;
|
|
42
42
|
state: string | Record<string, string>;
|
|
43
43
|
questions: {
|
|
44
|
-
q:
|
|
44
|
+
q: GatewayQuestion;
|
|
45
45
|
};
|
|
46
46
|
providerOptions: {
|
|
47
47
|
gateway: {
|
|
@@ -78,12 +78,12 @@ interface JevPluginConfig {
|
|
|
78
78
|
tool?: boolean;
|
|
79
79
|
/**
|
|
80
80
|
* AI Gateway reporting tags, for cost attribution. Defaults to `['feature:jev-fields']`.
|
|
81
|
-
* Each request also gets a per-
|
|
81
|
+
* Each request also gets a per-question tag, e.g. `jev.noul:article.readable`.
|
|
82
82
|
*/
|
|
83
83
|
tags?: string[];
|
|
84
84
|
}
|
|
85
85
|
/** @public */
|
|
86
|
-
interface
|
|
86
|
+
interface ChoiceQuestion extends QuestionBase {
|
|
87
87
|
type: 'choice';
|
|
88
88
|
/** Two to 255 options: option name → what it means. */
|
|
89
89
|
criteria: Record<string, string>;
|
|
@@ -97,7 +97,7 @@ interface ChoiceRule {
|
|
|
97
97
|
oneOf: string[];
|
|
98
98
|
}
|
|
99
99
|
/** One option from a named set. @public */
|
|
100
|
-
export declare const choice: (
|
|
100
|
+
export declare const choice: (question: Omit<ChoiceQuestion, "type">) => ChoiceQuestion;
|
|
101
101
|
interface ChoiceProbability {
|
|
102
102
|
_key: string;
|
|
103
103
|
_type?: 'jev.choiceProbability';
|
|
@@ -113,7 +113,7 @@ interface ChoiceValue extends EvaluatedValue {
|
|
|
113
113
|
probabilities?: ChoiceProbability[];
|
|
114
114
|
}
|
|
115
115
|
/** @public */
|
|
116
|
-
interface
|
|
116
|
+
interface NoulQuestion extends QuestionBase {
|
|
117
117
|
type: 'noul';
|
|
118
118
|
/** What a "yes" means. Shown when the probability is 50% or higher. */
|
|
119
119
|
true: string;
|
|
@@ -126,8 +126,8 @@ interface NoulSignal extends SignalBase {
|
|
|
126
126
|
/** Block publishing when the probability is outside these bounds (0–1). */
|
|
127
127
|
require?: RangeRule;
|
|
128
128
|
}
|
|
129
|
-
/** A yes/no
|
|
130
|
-
export declare const noul: (
|
|
129
|
+
/** A yes/no question: the chip shows the probability that the answer is yes. @public */
|
|
130
|
+
export declare const noul: (question: Omit<NoulQuestion, "type">) => NoulQuestion;
|
|
131
131
|
/** @public */
|
|
132
132
|
interface NoulValue extends EvaluatedValue {
|
|
133
133
|
_type?: 'jev.noul';
|
|
@@ -135,7 +135,7 @@ interface NoulValue extends EvaluatedValue {
|
|
|
135
135
|
probability?: number;
|
|
136
136
|
}
|
|
137
137
|
/** @public */
|
|
138
|
-
interface
|
|
138
|
+
interface ScoreQuestion extends QuestionBase {
|
|
139
139
|
type: 'score';
|
|
140
140
|
/**
|
|
141
141
|
* Two to ten criteria, lowest first. Text before a colon becomes the short label,
|
|
@@ -154,7 +154,7 @@ interface ScoreSignal extends SignalBase {
|
|
|
154
154
|
require?: RangeRule;
|
|
155
155
|
}
|
|
156
156
|
/** A position on an ordered scale. @public */
|
|
157
|
-
export declare const score: (
|
|
157
|
+
export declare const score: (question: Omit<ScoreQuestion, "type">) => ScoreQuestion;
|
|
158
158
|
/** @public */
|
|
159
159
|
interface ScoreValue extends EvaluatedValue {
|
|
160
160
|
_type?: 'jev.score';
|
|
@@ -167,8 +167,8 @@ interface ScoreValue extends EvaluatedValue {
|
|
|
167
167
|
/** The model's confidence in this score (0–1). */
|
|
168
168
|
confidence?: number;
|
|
169
169
|
}
|
|
170
|
-
interface
|
|
171
|
-
/** Chip and detail heading. Defaults to the
|
|
170
|
+
interface QuestionBase {
|
|
171
|
+
/** Chip and detail heading. Defaults to the question's key, e.g. `readable` → "Readable". */
|
|
172
172
|
title?: string;
|
|
173
173
|
/** The question Jev answers about the attached field. */
|
|
174
174
|
instructions: string;
|
|
@@ -186,11 +186,11 @@ interface RangeRule {
|
|
|
186
186
|
atMost?: number;
|
|
187
187
|
}
|
|
188
188
|
/** @public */
|
|
189
|
-
type
|
|
190
|
-
/**
|
|
191
|
-
type
|
|
189
|
+
type JevQuestion = NoulQuestion | ScoreQuestion | ChoiceQuestion;
|
|
190
|
+
/** Questions attached to a field, keyed by the name of the field that stores each answer. */
|
|
191
|
+
type JevQuestions = Record<string, JevQuestion>;
|
|
192
192
|
/**
|
|
193
|
-
* Adds a field that stores each
|
|
193
|
+
* Adds a field that stores each question's answer next to every field with `options.jev`.
|
|
194
194
|
* Plugins can't see the Studio's own schema types, so wrap them in `sanity.config`:
|
|
195
195
|
*
|
|
196
196
|
* ```ts
|
|
@@ -209,7 +209,7 @@ export declare const JEV_NAMESPACE: "jev";
|
|
|
209
209
|
declare const resources: {
|
|
210
210
|
readonly 'strip.label': "Jev";
|
|
211
211
|
readonly 'strip.set-up': "Set up Jev";
|
|
212
|
-
readonly 'strip.evaluate-all': "Evaluate all
|
|
212
|
+
readonly 'strip.evaluate-all': "Evaluate all questions now";
|
|
213
213
|
readonly 'chip.empty': "–";
|
|
214
214
|
readonly 'chip.error': "Error";
|
|
215
215
|
readonly 'chip.out-of-date': "Out of date";
|
|
@@ -239,7 +239,7 @@ declare const resources: {
|
|
|
239
239
|
readonly 'key-dialog.saving': "Saving…";
|
|
240
240
|
readonly 'key-dialog.save-failed': "Could not save the key: {{error}}";
|
|
241
241
|
readonly 'tool.title': "Jev";
|
|
242
|
-
readonly 'tool.intro': "Jev
|
|
242
|
+
readonly 'tool.intro': "Jev questions are answered by TypeSafe’s Jev model through Vercel AI Gateway.";
|
|
243
243
|
readonly 'tool.key.heading': "AI Gateway API key";
|
|
244
244
|
readonly 'tool.key.status.config': "From plugin config";
|
|
245
245
|
readonly 'tool.key.status.checking': "Checking";
|
|
@@ -250,11 +250,11 @@ declare const resources: {
|
|
|
250
250
|
readonly 'tool.key.ends-with': "Key ending in <Code>{{last4}}</Code>";
|
|
251
251
|
readonly 'tool.key.changed': "Last changed {{date}}";
|
|
252
252
|
readonly 'tool.key.checking': "Checking for a stored key…";
|
|
253
|
-
readonly 'tool.key.none': "No key is stored, so Jev
|
|
253
|
+
readonly 'tool.key.none': "No key is stored, so Jev questions can’t be evaluated yet.";
|
|
254
254
|
readonly 'tool.key.set': "Set key";
|
|
255
255
|
readonly 'tool.key.change': "Change key";
|
|
256
256
|
readonly 'tool.key.remove': "Remove key";
|
|
257
|
-
readonly 'tool.key.remove-confirm': "Remove the key? Jev
|
|
257
|
+
readonly 'tool.key.remove-confirm': "Remove the key? Jev questions stop being evaluated until a new one is set.";
|
|
258
258
|
readonly 'tool.key.remove-cancel': "Cancel";
|
|
259
259
|
readonly 'tool.key.remove-confirm-button': "Remove";
|
|
260
260
|
readonly 'tool.key.remove-failed': "Could not remove the key: {{error}}";
|
|
@@ -268,16 +268,16 @@ declare const resources: {
|
|
|
268
268
|
type JevTranslationKey = keyof typeof resources;
|
|
269
269
|
declare module 'sanity' {
|
|
270
270
|
interface BaseSchemaTypeOptions {
|
|
271
|
-
/** Jev
|
|
272
|
-
jev?:
|
|
271
|
+
/** Jev questions shown on this field, keyed by the name of the field storing each answer. */
|
|
272
|
+
jev?: JevQuestions;
|
|
273
273
|
}
|
|
274
274
|
}
|
|
275
275
|
/**
|
|
276
|
-
* Jev
|
|
276
|
+
* Jev questions for Sanity Studio: yes/no, score and choice questions attached to a field with
|
|
277
277
|
* `options.jev`, answered by TypeSafe's Jev model through Vercel AI Gateway. Pair it with
|
|
278
278
|
* `withJevAnswers(schemaTypes)` in `schema.types`.
|
|
279
279
|
* @public
|
|
280
280
|
*/
|
|
281
281
|
export declare const jev: import("sanity").Plugin<void | JevPluginConfig>;
|
|
282
|
-
export type {
|
|
282
|
+
export type { ChoiceQuestion, ChoiceRule, ChoiceValue, GatewayAnswer, GatewayQuestion, JevPluginConfig, JevQuestion, JevQuestions, JevRequest, JevTranslationKey, JevTransport, NoulQuestion, NoulValue, RangeRule, ScoreQuestion, ScoreValue };
|
|
283
283
|
//# sourceMappingURL=index.d.ts.map
|