generated from explainers-by-googlers/template
-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathindex.bs
More file actions
548 lines (360 loc) · 30.7 KB
/
index.bs
File metadata and controls
548 lines (360 loc) · 30.7 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
<pre class='metadata'>
Title: Proofreader API
Shortname: proofreader
Level: None
Status: CG-DRAFT
Group: webml
Repository: webmachinelearning/proofreader-api
URL: https://webmachinelearning.github.io/proofreader-api
Editor: Qianqia (Queenie) Zhang, Google https://google.com, queeniezhang@google.com
Editor: Reilly Grant 83788, Google https://www.google.com, reillyg@google.com
Abstract: The proofreader API provides high-level interfaces to call on browser or operating system's built-in language model to help with proofreading tasks.
Markup Shorthands: markdown yes, css no
Complain About: accidental-2119 yes, missing-example-ids yes
Assume Explicit For: yes
Die On: warning
</pre>
<pre class="anchors">
urlPrefix: https://tc39.es/ecma402/; spec: ECMA-402
type: dfn; text: [[AvailableLocales]]; url: sec-internal-slots
type: dfn; text: Unicode canonicalized locale identifier; url: sec-language-tags
type: abstract-op; text: LookupMatchingLocaleByBestFit; url: sec-lookupmatchinglocalebybestfit
type: abstract-op; text: IsStructurallyValidLanguageTag; url: sec-isstructurallyvalidlanguagetag
type: abstract-op; text: CanonicalizeUnicodeLocaleId; url: sec-canonicalizeunicodelocaleid
urlPrefix: https://tc39.es/ecma262/; spec: ECMA-262
type: abstract-op; text: floor; url: eqn-floor
type: dfn; text: current realm; url: current-realm
</pre>
<style>
dl.props { display: grid; grid-template-columns: max-content auto; row-gap: 0.25em; column-gap: 1em; }
dl.props > dt { grid-column-start: 1; margin: 0; }
dl.props > dd { grid-column-start: 2; margin: 0; }
p + dl.props { margin-top: -0.5em; }
.enum-table tbody th { white-space: nowrap; }
</style>
<h2 id="intro">Introduction</h2>
For now, see the [explainer](https://github.com/webmachinelearning/proofreader-api/blob/main/README.md).
<h2 id="dependencies">Dependencies</h2>
These APIs are part of a family of APIs expected to be powered by machine learning models, which share common API surface idioms and specification patterns. Currently, the specification text for these shared parts lives in [[WRITING-ASSISTANCE-APIS#supporting]], and the common privacy and security considerations are discussed in [[WRITING-ASSISTANCE-APIS#privacy]] and [[WRITING-ASSISTANCE-APIS#security]]. Implementing these APIs requires implementing that shared infrastructure, and conforming to those privacy and security considerations. But it does not require implementing or exposing the actual writing assistance APIs. [[!WRITING-ASSISTANCE-APIS]]
<h2 id="proofreader-api">The proofreader API</h2>
<xmp class="idl">
[Exposed=Window, SecureContext]
interface Proofreader {
static Promise<Proofreader> create(optional ProofreaderCreateOptions options = {});
static Promise<Availability> availability(optional ProofreaderCreateCoreOptions options = {});
Promise<ProofreadResult> proofread(
DOMString input,
optional ProofreaderProofreadOptions options = {}
);
readonly attribute boolean includeCorrectionTypes;
readonly attribute boolean includeCorrectionExplanations;
readonly attribute FrozenArray<DOMString>? expectedInputLanguages;
readonly attribute DOMString? correctionExplanationLanguage;
};
dictionary ProofreaderCreateCoreOptions {
boolean includeCorrectionTypes = false;
boolean includeCorrectionExplanations = false;
sequence<DOMString> expectedInputLanguages;
DOMString correctionExplanationLanguage;
};
dictionary ProofreaderCreateOptions : ProofreaderCreateCoreOptions {
AbortSignal signal;
CreateMonitorCallback monitor;
};
dictionary ProofreaderProofreadOptions {
AbortSignal signal;
};
dictionary ProofreadResult {
DOMString correctedInput;
sequence<ProofreadCorrection> corrections;
};
dictionary ProofreadCorrection {
unsigned long long startIndex;
unsigned long long endIndex;
DOMString correction;
sequence<CorrectionType> types;
DOMString explanation;
};
enum CorrectionType { "spelling", "punctuation", "capitalization", "grammar" };
</xmp>
<h3 id="proofreader-creation">Creation</h3>
<div algorithm>
The static <dfn method for="Proofreader">create(|options|)</dfn> method steps are:
1. Return the result of [=creating an AI model object=] given |options|, "{{Proofreader}}", [=validate and canonicalize proofreader options=], [=compute proofreader options availability=], [=download the proofreader model=], [=initialize the proofreader model=], [=create a proofreader object=], and false.
</div>
<div algorithm>
To <dfn>validate and canonicalize proofreader options</dfn> given a {{ProofreaderCreateCoreOptions}} |options|, perform the following steps. They mutate |options| in place to canonicalize and deduplicate language tags, and throw an exception if any are invalid.
1. [=Validate and canonicalize language tags=] given |options| and "{{ProofreaderCreateCoreOptions/expectedInputLanguages}}".
1. [=Validate and canonicalize language tags=] given |options| and "{{ProofreaderCreateCoreOptions/correctionExplanationLanguage}}".
</div>
<div algorithm>
To <dfn>download the proofreader model</dfn>, given a {{ProofreaderCreateCoreOptions}} |options|:
1. [=Assert=]: these steps are running [=in parallel=].
1. Initiate the download process for everything the user agent needs to proofread text according to |options|. This could include a base AI model, fine-tunings for specific languages or option values, or other resources.
1. If the download process cannot be started for any reason, then return false.
1. Return true.
</div>
<div algorithm>
To <dfn>initialize the proofreader model</dfn>, given a {{ProofreaderCreateOptions}} |options|:
1. [=Assert=]: these steps are running [=in parallel=].
1. Perform any necessary initialization operations for the AI model backing the user agent's proofreading capabilities.
This could include loading the model into memory, or loading any fine-tunings necessary to support the other options expressed by |options|.
1. If initialization failed for any other reason, then return a [=DOMException error information=] whose [=DOMException error information/name=] is "{{OperationError}}" and whose [=DOMException error information/details=] contain appropriate detail.
1. Return null.
</div>
<div algorithm>
To <dfn>create a proofreader object</dfn>, given a [=ECMAScript/realm=] |realm| and a {{ProofreaderCreateOptions}} |options|:
1. [=Assert=]: these steps are running on |realm|'s [=ECMAScript/surrounding agent=]'s [=agent/event loop=].
1. Return a new {{Proofreader}} object, created in |realm|, with
<dl class="props">
: [=Proofreader/include correction types=]
:: |options|["{{ProofreaderCreateCoreOptions/includeCorrectionTypes}}"] default to false
: [=Proofreader/include correction explanations=]
:: |options|["{{ProofreaderCreateCoreOptions/includeCorrectionExplanations}}"] default to false
: [=Proofreader/expected input languages=]
:: the result of [=creating a frozen array=] given |options|["{{ProofreaderCreateCoreOptions/expectedInputLanguages}}"] if it [=set/is empty|is not empty=]; otherwise null
: [=Proofreader/correction explanation language=]
:: |options|["{{ProofreaderCreateCoreOptions/correctionExplanationLanguage}}"] if it [=map/exists=]; otherwise null
</dl>
</div>
<h3 id="proofreader-availability">Availability</h3>
<div algorithm>
The static <dfn method for="Proofreader">availability(|options|)</dfn> method steps are:
1. Return the result of [=computing AI model availability=] given |options|, "{{Proofreader}}", [=validate and canonicalize proofreader options=], and [=compute proofreader options availability=].
</div>
<div algorithm>
To <dfn>compute proofreader options availability</dfn> given a {{ProofreaderCreateCoreOptions}} |options|, perform the following steps. They return either an {{Availability}} value or null, and they mutate |options| in place to update language tags to their best-fit matches.
1. [=Assert=]: this algorithm is running [=in parallel=].
1. Let |availability| be the [=proofreader non-language options availability=] given |options|["{{ProofreaderCreateCoreOptions/includeCorrectionTypes}}"], |options|["{{ProofreaderCreateCoreOptions/includeCorrectionExplanations}}"].
1. Let |double| be the [=proofreader language availabilities double=].
1. If |double| is null, then return null.
1. Let |inputLanguageAvailability| be the result of [=computing language availability=] given |options|["{{ProofreaderCreateCoreOptions/expectedInputLanguages}}"] and |double|'s [=language availabilities double/input languages=].
1. Let |correctionExplanationLanguagesList| be « |options|["{{ProofreaderCreateCoreOptions/correctionExplanationLanguage}}"] ».
1. Let |correctionExplanationLanguageAvailability| be the result of [=computing language availability=] given |correctionExplanationLanguagesList| and |double|'s [=language availabilities double/correction explanation languages=].
1. Set |options|["{{ProofreaderCreateCoreOptions/correctionExplanationLanguage}}"] to |correctionExplanationLanguagesList|[0].
1. Return the [=Availability/minimum availability=] given « |availability|, |inputLanguageAvailability|, |correctionExplanationLanguageAvailability| ».
</div>
<div algorithm>
The <dfn>proofreader non-language options availability</dfn>, given a boolean |includeCorrectionTypes| and a boolean |includeCorrectionExplanations|, is given by the following steps. They return an {{Availability}} value or null.
1. [=Assert=]: this algorithm is running [=in parallel=].
1. If there is some error attempting to determine whether the user agent [=model availability/can support=] proofreading text, which the user agent believes to be transient (such that re-querying could stop producing such an error), then return null.
1. If the user agent [=model availability/currently supports=] proofreading text with/without correction types as described by |includeCorrectionTypes| and with/without correction explanations as described by |includeCorrectionExplanations|, then return "{{Availability/available}}".
1. If the user agent believes it will be able to [=model availability/support=] proofreading text according to |includeCorrectionTypes| and |includeCorrectionExplanations|, but only after finishing a download that is already ongoing, then return "{{Availability/downloading}}".
1. If the user agent believes it will be able to [=model availability/support=] proofreading text according to |includeCorrectionTypes| and |includeCorrectionExplanations|, but only after performing a not-currently-ongoing download, then return "{{Availability/downloadable}}".
1. Otherwise, return "{{Availability/unavailable}}".
</div>
<div algorithm>
The <dfn>proofreader language availabilities double</dfn> is given by the following steps. They return a [=language availabilities double=] or null.
1. [=Assert=]: this algorithm is running [=in parallel=].
1. If there is some error attempting to determine whether the user agent [=model availability/can support=] proofreading text, which the user agent believes to be transient (such that re-querying could stop producing such an error), then return null.
1. Return a [=language availabilities double=] with:
<dl class="props">
: [=language availabilities double/input languages=]
:: the result of [=getting the language availabilities partition=] given the purpose of proofreading text written in that language
: [=language availabilities double/correction explanation languages=]
:: the result of [=getting the language availabilities partition=] given the purpose of producing text explanations of proofreading corrections in that language
</dl>
</div>
<div class="example" id="example-subtags-chinese">
A common setup seen in today's software is to support two types of written Chinese: "traditional Chinese" and "simplified Chinese". Let's suppose that the user agent supports proofreading text written in traditional Chinese with no downloads, and simplified Chinese after a download.
One way this could be implemented would be for [=proofreader language availabilities double=] to return that "`zh-Hant`" is in the [=language availabilities double/input languages=]["{{Availability/available}}"] set, and "`zh`" and "`zh-Hans`" are in the [=language availabilities double/input languages=]["{{Availability/downloadable}}"] set. This return value conforms to the requirements of the language tag set completeness rules, in ensuring that "`zh`" is present. Per <a class="allow-2119" href="#language-tag-completeness-implementation-defined">the "should"-level guidance</a>, the implementation has determined that "`zh`" belongs in the set of downloadable input languages, with "`zh-Hans`", instead of in the set of available input languages, with "`zh-Hant`".
Combined with the use of [$LookupMatchingLocaleByBestFit$], this means {{Proofreader/availability()}} will give the following answers:
<xmp class="language-js">
function a(languageTag) {
return Proofreader.availability({
expectedInputLanguages: [languageTag]
});
}
await a("zh") === "downloadable";
await a("zh-Hant") === "available";
await a("zh-Hans") === "downloadable";
await a("zh-TW") === "available"; // zh-TW will best-fit to zh-Hant
await a("zh-HK") === "available"; // zh-HK will best-fit to zh-Hant
await a("zh-CN") === "downloadable"; // zh-CN will best-fit to zh-Hans
await a("zh-BR") === "downloadable"; // zh-BR will best-fit to zh
await a("zh-Kana") === "downloadable"; // zh-Kana will best-fit to zh
</xmp>
</div>
<h3 id="supporting-language-availability">Language availability</h3>
A <dfn>language availabilities partition</dfn> is a [=map=] whose [=map/keys=] are "{{Availability/downloading}}", "{{Availability/downloadable}}", or "{{Availability/available}}", and whose [=map/values=] are [=sets=] of strings representing [=Unicode canonicalized locale identifiers=]. [[!ECMA-402]]
A <dfn>language availabilities double</dfn> is a [=struct=] with the following [=struct/items=]:
* <dfn for="language availabilities double">input languages</dfn>, a [=language availabilities partition=]
* <dfn for="language availabilities double">correction explanation languages</dfn>, a [=language availabilities partition=]
<div algorithm>
To <dfn export>get the language availabilities partition</dfn> given a description |purpose| of the purpose for which we're checking language availability:
1. Let |partition| be «[ "{{Availability/available}}" → an empty [=set=], "{{Availability/downloading}}" → an empty [=set=], "{{Availability/downloadable}}" → an empty [=set=] ]».
1. [=list/For each=] human language |languageTag|, represented as a [=Unicode canonicalized locale identifier=], for which the user agent [=model availability/currently supports=] |purpose|:
1. [=set/Append=] |languageTag| to |partition|["{{Availability/available}}"].
1. [=list/For each=] human language |languageTag|, represented as a [=Unicode canonicalized locale identifier=], for which the user agent believes it will be able to [=model availability/support=] |purpose|, but only after finishing a download that is already ongoing:
1. [=set/Append=] |languageTag| to |partition|["{{Availability/downloading}}"].
1. [=list/For each=] human language |languageTag|, represented as a [=Unicode canonicalized locale identifier=], for which the user agent believes it will be able to [=model availability/support=] |purpose|, but only after performing a not-currently-ongoing download:
1. [=set/Append=] |languageTag| to |partition|["{{Availability/downloadable}}"].
1. [=Assert=]: |partition|["{{Availability/available}}"], |partition|["{{Availability/downloading}}"], and |partition|["{{Availability/downloadable}}"] are disjoint.
1. If the [=set/union=] of |partition|["{{Availability/available}}"], |partition|["{{Availability/downloading}}"], and |partition|["{{Availability/downloadable}}"] does not meet the language tag set completeness rules, then:
1. Let |missingLanguageTags| be the [=set=] of missing language tags necessary for that union to meet the language tag set completeness rules.
1. [=set/For each=] |languageTag| of |missingLanguageTags|:
1. <span id="language-tag-completeness-implementation-defined"></span> [=set/Append=] |languageTag| to one of the three sets. Which of the sets to append to is [=implementation-defined=], and should be guided by considerations similar to that of [$LookupMatchingLocaleByBestFit$] in terms of keeping "best fallback languages" together.
1. Return |partition|.
</div>
<div algorithm>
To <dfn export>compute language availability</dfn> given an [=ordered set=] of strings |requestedLanguages| and a [=language availabilities partition=] |partition|, perform the following steps. They return an {{Availability}} value, and they mutate |requestedLanguages| in place to update language tags to their best-fit matches.
1. Let |availability| be "{{Availability/available}}".
1. [=set/For each=] |language| of |requestedLanguages|:
1. Let |unavailable| be true.
1. [=list/For each=] |availabilityToCheck| of « "{{Availability/available}}", "{{Availability/downloading}}", "{{Availability/downloadable}}" »:
1. Let |languagesWithThisAvailability| be |partition|[|availabilityToCheck|].
1. Let |bestMatch| be [$LookupMatchingLocaleByBestFit$](|languagesWithThisAvailability|, « |language| »).
1. If |bestMatch| is not undefined, then:
1. [=list/Replace=] |language| with |bestMatch|.\[[locale]] in |requestedLanguages|.
1. Set |availability| to the [=Availability/minimum availability=] given |availability| and |availabilityToCheck|.
1. Set |unavailable| to false.
1. [=iteration/Break=].
1. If |unavailable| is true, then return "{{Availability/unavailable}}".
1. Return |availability|.
</div>
<h3 id="the-proofreader-class">The {{Proofreader}} class</h3>
Every {{Proofreader}} has a <dfn for="Proofreader">include correction type</dfn>, a [=boolean=] or default to false, set during creation.
Every {{Proofreader}} has a <dfn for="Proofreader">include correction explanations</dfn>, a [=boolean=] or default to false, set during creation.
Every {{Proofreader}} has an <dfn for="Proofreader">expected input languages</dfn>, a <code>{{FrozenArray}}<{{DOMString}}></code> or null, set during creation.
Every {{Proofreader}} has an <dfn for="Proofreader">correction explanation language</dfn>, a [=string=] or null, set during creation.
<hr>
The <dfn attribute for="Proofreader">includeCorrectionTypes</dfn> getter steps are to return [=this=]'s [=Proofreader/include correction types=].
The <dfn attribute for="Proofreader">type</dfn> getter steps are to return [=this=]'s [=Proofreader/include correction explanations=].
The <dfn attribute for="Proofreader">expectedInputLanguages</dfn> getter steps are to return [=this=]'s [=Proofreader/expected input languages=].
The <dfn attribute for="Proofreader">correctionExplanationLanguage</dfn> getter steps are to return [=this=]'s [=Proofreader/correction explanation language=].
<hr>
<div algorithm>
The <dfn method for="Proofreader">proofread(|input|, |options|)</dfn> method steps are:
1. Let |operation| be an algorithm step which takes arguments |chunkProduced|, |done|, |error|, and |stopProducing|, and proofreads |input| given [=this=]'s [=Proofreader/include correction types=], [=this=]'s [=Proofreader/include correction explanations=], [=this=]'s [=Proofreader/correction explanation language=], |chunkProduced|, |done|, |error|, and |stopProducing|.
1. Return the result of [=getting an aggregated AI model result=] given [=this=], |options|, and |operation|.
</div>
<div algorithm>
The <dfn method for="Proofreader">measureInputUsage(|input|, |options|)</dfn> method steps are:
1. Let |measureUsage| be an algorithm step which takes argument |stopMeasuring|, and returns the result of measuring proofreader input usage given |input|, [=this=]'s [=Proofreader/include correction types=], [=this=]'s [=Proofreader/include correction explanations=], [=this=]'s [=Proofreader/correction explanation language=], and |stopMeasuring|.
1. Return the result of [=measuring AI model input usage=] given [=this=], |options|, and |measureUsage|.
</div>
<h3 id="proofreader-proofreading">Proofreading</h3>
<h4 id="proofreader-algorithm">The algorithm</h4>
<div algorithm>
To <dfn>proofread</dfn> given:
* a [=string=] |input|,
* a [=boolean=] |includeCorrectionTypes|,
* a [=boolean=] |includeCorrectionExplanations|,
* a [=string=]-or-null |correctionExplanationLanguage|,
* an algorithm |chunkProduced| that takes a [=string=] and returns nothing,
* an algorithm |done| that takes no arguments and returns nothing,
* an algorithm |error| that takes [=error information=] and returns nothing, and
* an algorithm |stopProducing| that takes no arguments and returns a boolean,
perform the following steps:
1. [=Assert=]: this algorithm is running [=in parallel=].
1. Let |requested| be the result of [=measuring proofreader input usage=] given |input|, |includeCorrectionTypes|, |correctionExplanationLanguage|, |correctionExplanationLanguage|, and |stopProducing|.
1. If |requested| is null, then return.
1. If |requested| is an [=error information=], then:
1. Perform |error| given |requested|.
1. Return.
1. [=Assert=]: |requested| is a number.
1. In an [=implementation-defined=] manner, subject to the following guidelines, begin the process of proofreading |input| into a {{ProofreadResult}} with a [=string=] |correctedInput| as the proofread text and a {{ProofreadCorrection}} corrections detailing all the corrections made to |input| to form |correctedInput|.
If |input| is the empty string, or otherwise consists of no proofreadable content (e.g., only contains whitespace, or control characters), then the resulting proofread text should be the empty string. In such cases, |includeCorrectionTypes|, |includeCorrectionExplanations|, and |correctionExplanationLanguage| should be ignored.
The proofreading should conform to the guidance given by |includeCorrectionTypes| and |includeCorrectionExplanations|.
The proofreading process must conform to the guidance given in [[#privacy]] and [[#security]], notably including (but not limited to) [[WRITING-ASSISTANCE-APIS#privacy-user-input]] and [[WRITING-ASSISTANCE-APIS#security-runtime]].
If |correctionExplanationLanguage| is non-null, the proofreading should be in that language. Otherwise, it should be in the language of |input|. If |input| contains multiple languages, or the language of |input| cannot be detected, then either the correction explanation language is [=implementation-defined=], or the implementation may treat this as an error, per the guidance in [[#proofreader-errors]].
Implementers should do their utmost to ensure that the result is an actual proofread result of |input|, and is not arbitrary output prompted by |input|.
<p class="example" id="example-bad-proofread-question-answering">For example, if |input| is "`what is capital of France`", then it would be incorrect to answer this question, e.g. by outputting "`Paris is the capital of France.`" A more correct output would be, e.g., "`What is the capital of France?`".
1. Wait for the next chunk of proofreading data to be produced, for the proofreading process to finish, or for the result of calling |stopProducing| to become true.
1. If such a chunk is successfully produced:
1. Let it be represented as a [=string=] |chunk|.
1. Perform |chunkProduced| given |chunk|.
1. Otherwise, if the proofreading process has finished:
1. Perform |done|.
1. [=iteration/Break=].
1. Otherwise, if |stopProducing| returns true, then [=iteration/break=].
1. Otherwise, if an error occurred during proofreading:
1. Let the error be represented as [=error information=] |errorInfo| according to the guidance in [[#proofreader-errors]].
1. Perform |error| given |errorInfo|.
1. [=iteration/Break=].
</div>
<h4 id="proofreader-usage">Usage</h4>
<div algorithm>
To <dfn>measure proofreader input usage</dfn>, given:
* a [=string=] |input|,
* a [=boolean=] |includeCorrectionTypes|,
* a [=boolean=] |includeCorrectionExplanations|,
* a [=string=]-or-null |correctionExplanationLanguage|, and
* an algorithm |stopMeasuring| that takes no arguments and returns a boolean,
perform the following steps:
1. [=Assert=]: this algorithm is running [=in parallel=].
1. Let |inputToModel| be the [=implementation-defined=] string that would be sent to the underlying model in order to [=proofread=] given |input|, |includeCorrectionTypes|, |includeCorrectionExplanations|, and |correctionExplanationLanguage|.
If during this process |stopMeasuring| starts returning true, then return null.
If an error occurs during this process, then return an appropriate [=DOMException error information=] according to the guidance in [[#proofreader-errors]].
1. Return the amount of input usage needed to represent |inputToModel| when given to the underlying model. The exact calculation procedure is [=implementation-defined=], subject to the following constraints.
The returned input usage must be nonnegative and finite. It must be 0, if there are no usage quotas for the proofreading process. Otherwise, it must be positive and should be roughly proportional to the [=string/length=] of |inputToModel|.
<p class="note" id="note-proofreader-input-usage">This might be the number of tokens needed to represent |input| in a <a href="https://arxiv.org/abs/2404.08335">language model tokenization scheme</a>, or it might be |input|'s [=string/length=]. It could also be some variation of these which also counts the usage of any prefixes or suffixes necessary to give to the model.
If during this process |stopMeasuring| starts returning true, then instead return null.
If an error occurs during this process, then instead return an appropriate [=DOMException error information=] according to the guidance in [[#proofreader-errors]].
</div>
<h4 id="proofreader-options">Options</h4>
The [=proofread=] algorithm's details are [=implementation-defined=], as they are expected to be powered by an AI model. However, it is intended to be controllable by the web developer through the |includeCorrectionTypes| and |includeCorrectionExplanations| flags.
This section gives normative guidance on how the implementation of [=proofread=] should use each boolean flag to guide the proofreading process.
<table class="data enum-table">
<caption>|includeCorrectionTypes| values</caption>
<thead>
<tr>
<th>Value
<th>Meaning
<tbody>
<tr>
<th>"true"
<td>
<p>The proofread result should contain a list of corrections where each {{ProofreadCorrection}}, defined by its range from |startIndex| to |endIndex|, should describe the types of errors that are corrected according to the {{CorrectionType}} enumeration.
<tr>
<th>"false"
<td>
<p>The proofread result should contain a list of corrections where each {{ProofreadCorrection}}, defined by its range from |startIndex| to |endIndex|, does not provide the types of errors that are corrected.
</table>
<table class="data enum-table">
<caption>|includeCorrectionExplanations| values</caption>
<thead>
<tr>
<th>Value
<th>Meaning
<tbody>
<tr>
<th>"true"
<td>
<p>The proofread result should contain a list of corrections where each {{ProofreadCorrection}}, defined by its range from |startIndex| to |endIndex|, should provide a text explanation for the errors corrected.
<tr>
<th>"false"
<td>
<p>The proofread result should contain a list of corrections where each {{ProofreadCorrection}}, defined by its range from |startIndex| to |endIndex|, does not provide the text explanation for the errors corrected.
</table>
<p class="note">As with all "<span class="allow-2119">should</span>"-level guidance, user agents might not conform perfectly to these. Especially in the case of providing correction types for all corrections, it's expected that language models might not conform perfectly.
<h4 id="proofreader-errors">Errors</h4>
When proofreading fails, the following possible reasons may be surfaced to the web developer. This table lists the possible {{DOMException}} [=DOMException/names=] and the cases in which an implementation should use them:
<table class="data">
<thead>
<tr>
<th>{{DOMException}} [=DOMException/name=]
<th>Scenarios
<tbody>
<tr>
<td>"{{NotAllowedError}}"
<td>
<p>Proofreading is disabled by user choice or user agent policy.
<tr>
<td>"{{NotSupportedError}}"
<td>
<p>The input to be proofread, or the context to be provided, was in a language that the user agent does not support, or was not provided properly in the call to {{Proofreader/create()}}.
<p>The proofreading correction explanation language ended up being in a language that the user agent does not support (e.g., because the user agent has not performed sufficient quality control tests on that output language), or was not provided properly in the call to {{Proofreader/create()}}.
<p>The |includeCorrectionExplanations| is set to true, the {{ProofreaderCreateCoreOptions/correctionExplanationLanguage}} option was not set, and the language of the input text could not be determined, so the user agent did not have a good correction explanation language default available.
<tr>
<td>"{{UnknownError}}"
<td>
<p>All other scenarios, including if the user agent believes it cannot proofread and also meet the requirements given in [[#privacy]] or [[#security]]. Or, if the user agent would prefer not to disclose the failure reason.
</table>
<p class="note">This table does not give the complete list of exceptions that can be surfaced by the proofreader API. It only contains those which can come from certain [=implementation-defined=] steps.
<h3 id="proofreader-permissions-policy">Permissions policy integration</h3>
Access to the proofreader API is gated behind the [=policy-controlled feature=] "<dfn permission>proofreader</dfn>", which has a [=policy-controlled feature/default allowlist=] of <code>[=default allowlist/'self'=]</code>.
<h2 id="privacy">Privacy considerations</h2>
Please see [[WRITING-ASSISTANCE-APIS#privacy]] for a discussion of privacy considerations for the translator and language detector APIs. That text was written to apply to all APIs sharing the same infrastructure, as noted in [[#dependencies]].
<h2 id="security">Security considerations</h2>
Please see [[WRITING-ASSISTANCE-APIS#security]] for a discussion of security considerations for the translator and language detector APIs. That text was written to apply to all APIs sharing the same infrastructure, as noted in [[#dependencies]].