Writing Assistance APIs

Draft Community Group Report,

More details about this document
This version:
https://webmachinelearning.github.io/writing-assistance-apis
Issue Tracking:
GitHub
Editor:
Domenic Denicola (Google)

Abstract

The summarizer, writer, and rewriter APIs provide high-level interfaces to call on a browser or operating system’s built-in language model to help with writing tasks.

Status of this document

This specification was published by the Web Machine Learning Community Group. It is not a W3C Standard nor is it on the W3C Standards Track. Please note that under the W3C Community Contributor License Agreement (CLA) there is a limited opt-out and other conditions apply. Learn more about W3C Community and Business Groups.

1. Introduction

For now, see the explainer.

2. Shared AI APIs and infrastructure

partial interface WindowOrWorkerGlobalScope {
  [Replaceable, SecureContext] readonly attribute AI ai;
};

[Exposed=(Window,Worker), SecureContext]
interface AI {};

[Exposed=(Window,Worker), SecureContext]
interface AICreateMonitor : EventTarget {
  attribute EventHandler ondownloadprogress;
};

callback AICreateMonitorCallback = undefined (AICreateMonitor monitor);

enum AICapabilityAvailability { "readily", "after-download", "no" };

Each WindowOrWorkerGlobalScope has an AI namespace, an AI object. Upon creation of the WindowOrWorkerGlobalScope object, its AI namespace must be set to a new AI object created in the WindowOrWorkerGlobalScope object’s relevant realm.

The ai getter steps are to return this's AI namespace.


Tasks queued by this specification use the AI task source.


The following are the event handlers (and their corresponding event handler event types) that must be supported, as event handler IDL attributes, by all AICreateMonitor objects:

Event handler Event handler event type
ondownloadprogress downloadprogress

3. The summarizer API

partial interface AI {
  readonly attribute AISummarizerFactory summarizer;
};

[Exposed=(Window,Worker), SecureContext]
interface AISummarizerFactory {
  Promise<AISummarizer> create(optional AISummarizerCreateOptions options = {});
  Promise<AISummarizerCapabilities> capabilities();
};

[Exposed=(Window,Worker), SecureContext]
interface AISummarizer {
  Promise<DOMString> summarize(
    DOMString input,
    optional AISummarizerSummarizeOptions options = {}
  );
  ReadableStream summarizeStreaming(
    DOMString input,
    optional AISummarizerSummarizeOptions options = {}
  );

  readonly attribute DOMString sharedContext;
  readonly attribute AISummarizerType type;
  readonly attribute AISummarizerFormat format;
  readonly attribute AISummarizerLength length;

  undefined destroy();
};

[Exposed=(Window,Worker), SecureContext]
interface AISummarizerCapabilities {
  readonly attribute AICapabilityAvailability available;

  AICapabilityAvailability createOptionsAvailable(
    optional AISummarizerCreateCoreOptions options = {}
  );
  AICapabilityAvailability languageAvailable(DOMString languageTag);
};

dictionary AISummarizerCreateCoreOptions {
  AISummarizerType type = "key-points";
  AISummarizerFormat format = "markdown";
  AISummarizerLength length = "short";
};

dictionary AISummarizerCreateOptions : AISummarizerCreateCoreOptions {
  AbortSignal signal;
  AICreateMonitorCallback monitor;

  DOMString sharedContext;
};

dictionary AISummarizerSummarizeOptions {
  AbortSignal signal;
  DOMString context;
};

enum AISummarizerType { "tl;dr", "teaser", "key-points", "headline" };
enum AISummarizerFormat { "plain-text", "markdown" };
enum AISummarizerLength { "short", "medium", "long" };

Each AI has an summarizer factory, an AISummarizerFactory object. Upon creation of the AI object, its summarizer factory must be set to a new AISummarizerFactory object created in the AI object’s relevant realm.

The summarizer getter steps are to return this's summarizer factory.

3.1. Creation

The create(options) method steps are:
  1. If this's relevant global object is a Window whose associated Document is not fully active, then return a promise rejected with an "InvalidStateError" DOMException.

  2. If options["signal"] exists and is aborted, then return a promise rejected with options["signal"]'s abort reason.

  3. Let fireProgressEvent be an algorithm taking two arguments that does nothing.

  4. If options["monitor"] exists, then:

    1. Let monitor be a new AICreateMonitor created in this's relevant realm.

    2. Invoke options["monitor"] with « monitor » and "rethrow".

      If an exception e is thrown, return a promise rejected with e.

    3. Set fireProgressEvent to an algorithm taking arguments loaded and total, which performs the following steps:

      1. Assert: this algorithm is running in parallel.

      2. Queue a global task on the AI task source given this's relevant global object to perform the following steps:

        1. Fire an event named downloadprogress at monitor, using ProgressEvent, with the loaded attribute initialized to loaded, the total attribute initialized to total, and the lengthComputable attribute initialized to true.

  5. Let abortedDuringDownload be false.

    This variable will be written to from the event loop, but read from in parallel.

  6. If options["signal"] exists, then add the following abort steps to options["signal"]:

    1. Set abortedDuringDownload to true.

  7. Let promise be a new promise created in this's relevant realm.

  8. In parallel:

    1. Let availability be the current summarizer create options availability given options["type"], options["format"], and options["length"].

    2. Switch on availability:

    null
    1. Reject promise with an "UnknownError" DOMException.

    2. Abort these steps.

    "no"
    1. Reject promise with a "NotSupportedError" DOMException.

    2. Abort these steps.

    "readily"
    1. If initializing the summarization model given promise and options returns false, then abort these steps.

    2. Let totalBytes be the total size of the previously-downloaded summarization capabilities, in bytes.

    3. Assert: totalBytes is greater than 0.

    4. Perform fireProgressEvent given 0 and totalBytes.

    5. Perform fireProgressEvent given totalBytes and totalBytes.

    6. Finalize summarizer creation given promise and options.

    "after-download"
    1. Initiate the download process for everything the user agent needs to summarize text according to options["type"], options["format"], or options["length"].

    2. Run the following steps, but abort when abortedDuringDownload becomes true:

      1. Wait for the total number of bytes to be downloaded to become determined, and let that number be totalBytes.

      2. Let lastProgressTime be the monotonic clock's unsafe current time.

      3. Perform fireProgressEvent given 0 and totalBytes.

      4. While true:

        1. If one or more bytes have been downloaded, then:

          1. If the monotonic clock's unsafe current time minus lastProgressTime is greater than 50 ms, then:

            1. Let bytesSoFar be the number of bytes downloaded so far.

            2. Assert: bytesSoFar is greater than 0 and less than or equal to totalBytes.

            3. Perform fireProgressEvent given bytesSoFar and totalBytes.

            4. If bytesSoFar equals totalBytes, then break.

            5. Set lastProgressTime to the monotonic clock's unsafe current time.

        2. Otherwise, if downloading has failed and cannot continue, then:

          1. Queue a global task on the AI task source given this's relevant global object to reject promise with a "NetworkError" DOMException.

          2. Abort these steps.

    3. If aborted, then:

      1. Queue a global task on the AI task source given this's relevant global object to perform the following steps:

        1. Assert: options["signal"]'s is aborted.

        2. Reject promise with options["signal"]'s abort reason.

      2. Abort these steps.

    4. If initializing the summarization model given promise and options returns false, then abort these steps.

    5. Finalize summarizer creation given promise and options.

  9. Return promise.

To initialize the summarization model, given a Promise promise and an AISummarizerCreateOptions options:
  1. Assert: these steps are running in parallel.

  2. Perform any necessary initialization operations for the AI model backing the user agent's summarization capabilities.

    This could include loading the model into memory, loading options["sharedContext"] into the model’s context window, or loading any fine-tunings necessary to support options["type"], options["format"], or options["length"].

  3. If initialization failed for any reason, then:

    1. Queue a global task on the AI task source given promise’s relevant global object to reject promise with an "OperationError" DOMException.

    2. Return false.

  4. Return true.

To finalize summarizer creation, given a Promise promise and an AISummarizerCreateOptions options:
  1. Assert: these steps are running in parallel.

  2. Assert: the current summarizer create options availability for options["type"], options["format"], and options["length"] is "readily".

  3. Queue a global task on the AI task source given promise’s relevant global object to perform the following steps:

    1. If options["signal"] exists and is aborted, then:

      1. Reject promise with options["signal"]'s abort reason.

      2. Abort these steps.

      This check is necessary in case any code running on the event loop caused the AbortSignal to become aborted before this task ran.

    2. Let summarizer be a new AISummarizer object, created in promise’s relevant realm, with

      shared context

      options["sharedContext"] if it exists; otherwise null

      summary type

      options["type"]

      summary format

      options["format"]

      summary length

      options["length"]

    3. If options["signal"] exists, then add the following abort steps to options["signal"]:

      1. Destroy summarizer with options["signal"]'s abort reason.

    4. Resolve promise with summarizer.

3.2. Capabilities

The capabilities() method steps are:
  1. If this's relevant global object is a Window whose associated Document is not fully active, then return a promise rejected with an "InvalidStateError" DOMException.

  2. Let promise be a new promise created in this's relevant realm.

  3. In parallel:

    1. Let availableCreateOptions be a new map from tuples of (AISummarizerType, AISummarizerFormat, AISummarizerLength) values to AICapabilityAvailability values, initially empty.

    2. For each type of AISummarizerType's enumeration values:

      1. For each format of AISummarizerFormat's enumeration values:

        1. For each length of AISummarizerLength's enumeration values:

          1. Set availableCreateOptions[(type, format, length)] to the current summarizer create options availability given type, format, and length.

    3. Let « readilyAvailableLanguages, afterDownloadAvailableLanguages » be the current summarizer language availabilities.

    4. If readilyAvailableLanguages is null, afterDownloadAvailableLanguages is null, or availableCreateOptions’s values contains null, then queue a global task on the AI task source given this to perform the following steps:

      1. Reject promise with an "UnknownError" DOMException.

    5. Otherwise, queue a global task on the AI task source given this to perform the following steps:

      1. Let capabilitiesObject be a new AISummarizerCapabilities object, created in this's relevant realm, with

        available create options

        availableCreateOptions

        readily available languages

        readilyAvailableLanguages

        after-download available languages

        afterDownloadAvailableLanguages

      2. Resolve promise with capabilitiesObject.


Every AISummarizerCapabilities has an available create options, a map from tuples of (AISummarizerType, AISummarizerFormat, AISummarizerLength) values to AICapabilityAvailability values, set during creation.

Every AISummarizerCapabilities has an readily available languages, a set of strings representing BCP 47 language tags, set during creation.

Every AISummarizerCapabilities has an after-download available languages, a set of strings representing BCP 47 language tags, set during creation.

The available getter steps are:
  1. If this's readily available languages and after-download available languages are empty, then return "no".

  2. If this's all of this's available create options values are "no", then return "no".

  3. If this's readily available languages are empty, then return "after-download".

  4. Return "readily".

The createOptionsAvailable(options) method steps are:
  1. Return this's available create options[(options["type"], options["format"], options["length"])].

The languageAvailable(languageTag) method steps are:
  1. If IsStructurallyValidLanguageTag(languageTag) is false, then throw a TypeError.

  2. Set languageTag to CanonicalizeUnicodeLocaleId(languageTag).

  3. Let bestReadilyAvailableMatch be LookupMatchingLocaleByBestFit(this's readily available languages, languageTag).

  4. If bestReadilyAvailableMatch is not undefined, then return "readily".

    bestReadilyAvailableMatch.[[locale]] contains the actual language tag from this's readily available languages, which might be different from languageTag.

  5. Let bestAfterDownloadAvailableMatch be LookupMatchingLocaleByBestFit(this's after-download available languages, languageTag).

  6. If bestAfterDownloadAvailableMatch is not undefined, then return "after-download".

    bestAfterDownloadAvailableMatch.[[locale]] contains the actual language tag from this's after-download available languages, which might be different from languageTag.

  7. Return "no".


The current summarizer create options availability, given a AISummarizerType type, AISummarizerFormat format, and an AISummarizerLength length, is given by the following steps. They return an AICapabilityAvailability value or null.
  1. Assert: this algorithm is running in parallel.

  2. If the user agent supports summarizing text into the type of summary described by type, in the format described by format, and with the length guidance given by length without performing any downloading operations, then return "readily".

  3. If the user agent believes it can summarize text according to type, format, and length, but only after performing a download (e.g., of an AI model or fine-tuning), then return "after-download".

  4. If there is some error attempting to determine whether the user agent supports summarizing text, which the user agent believes to be transient (such that re-querying the current summarizer create options availability could stop producing such an error), then return null.

  5. Otherwise, return "no".

The current summarizer language availabilities are given by the following steps. They return a list containing two items; the items each are sets of strings representing Unicode canonicalized locale identifiers, or null. [ECMA-402]
  1. Assert: this algorithm is running in parallel.

  2. If there is some error attempting to determine whether the user agent supports summarizing text, which the user agent believes to be transient (such that re-querying the current summarizer language availabilities could stop producing such an error), then return « null, null ».

  3. Let readilyAvailableLanguages and afterDownloadAvailableLanguages be empty sets.

  4. For each human language languageTag, represented as a Unicode canonicalized locale identifier, for which the user agent supports summarizing text written in that language, without performing any downloading operations:

    1. Append languageTag to readilyAvailableLanguages.

  5. For each human language languageTag, represented as a Unicode canonicalized locale identifier, for which the user agent believes it can summarize text written in that language, but only after performing a download (e.g., of an AI model or fine-tuning):

    1. Assert: readilyAvailableLanguages does not contain languageTag.

    2. Append languageTag to afterDownloadAvailableLanguages.

  6. If the union of readilyAvailableLanguages and afterDownloadAvailableLanguages does not meet the language tag set completeness rules, then:

    1. Let missingLanguageTags be the set of missing language tags necessary to meet the language tag set completeness rules.

    2. For each languageTag of missingLanguageTags:

      1. Append languageTag to either readilyAvailableLanguages or afterDownloadAvailableLanguages. Which of the two 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.

  7. Return « readilyAvailableLanguages, afterDownloadAvailableLanguages ».

The language tag set completeness rules state that for every item languageTag, if languageTag has more than one subtag, then the set must also contain a less narrow language tag with the same language subtag and a strict subset of the same following subtags (i.e., omitting one or more).

This definition is intended to align with that of [[AvailableLocales]] in ECMAScript Internationalization API Specification. [ECMA-402]

This means that if an implementation supports summarization of "de-DE" text, it will also count as supporting "de" text.

The converse direction is supported not by the language tag set completeness rules, but instead by the use of LookupMatchingLocaleByBestFit, which ensures that if an implementation supports summarizing "de" text, it also counts as supporting summarization of "de-CH", "de-Latn-CH", etc.

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 summarizing text written in traditional Chinese readily, and simplified Chinese after a download.

One way this could be implemented would be for current summarizer language availabilities to return that « "zh-Hant" » is readily available, and « "zh", "zh-Hans" » is available after download. This return value conforms to the requirements of the language tag set completeness rules, in ensuring that "zh" is present. Per the "should"-level guidance, the implementation has determined that "zh" belongs in the list of after-download available languages, with "zh-Hans", instead of in the list of readily available languages, with "zh-Hant".

Combined with the use of LookupMatchingLocaleByBestFit, this means languageAvailable() will give the following answers:

c.languageAvailable("zh") === "after-download";
c.languageAvailable("zh-Hant") === "readily";
c.languageAvailable("zh-Hans") === "after-download";

c.languageAvailable("zh-TW") === "readily";          // zh-TW will best-fit to zh-Hant
c.languageAvailable("zh-HK") === "readily";          // zh-HK will best-fit to zh-Hant
c.languageAvailable("zh-CN") === "after-download";   // zh-CN will best-fit to zh-Hans

c.languageAvailable("zh-BR") === "after-download";   // zh-BR will best-fit to zh
c.languageAvailable("zh-Kana") === "after-download"; // zh-Kana will best-fit to zh

3.3. The AISummarizer class

Every AISummarizer has a shared context, a string-or-null, set during creation.

Every AISummarizer has a summary type, an AISummarizerType, set during creation.

Every AISummarizer has a summary format, an AISummarizerFormat, set during creation.

Every AISummarizer has a summary length, an AISummarizerLength, set during creation.

Every AISummarizer has a destruction reason, a JavaScript value, initially undefined.

Every AISummarizer has a destroyed boolean, initially false.

This value is separate from the destruction reason so that it can be read from in parallel during the summarization process.


The sharedContext getter steps are to return this's shared context.

The type getter steps are to return this's summary type.

The format getter steps are to return this's summary format.

The length getter steps are to return this's summary length.


The summarize(input, options) method steps are:
  1. If this's relevant global object is a Window whose associated Document is not fully active, then return a promise rejected with an "InvalidStateError" DOMException.

  2. If this's destroyed is true, then return a promise rejected with this's destruction reason.

  3. If options["signal"] exists and is aborted, then return a promise rejected with options["signal"]'s abort reason.

  4. Let abortedDuringSummarization be false.

    This variable will be written to from the event loop, but read from in parallel.

  5. If options["signal"] exists, then add the following abort steps to options["signal"]:

    1. Set abortedDuringSummarization to true.

  6. Let promise be a new promise created in this's relevant realm.

  7. Let context be options["context"] if it exists; otherwise null.

  8. In parallel:

    1. Let summary be the empty string.

    2. Let chunkProduced be the following steps given a string chunk:

      1. Queue a global task on the AI task source given this's relevant global object to perform the following steps:

        1. If abortedDuringSummarization is true, then:

          1. Reject promise with options["signal"]'s abort reason.

          2. Abort these steps.

        2. If this's destroyed is true, then:

          1. Reject promise with this's destruction reason.

          2. Abort these steps.

        3. Append chunk to summary.

    3. Let done be the following steps:

      1. Queue a global task on the AI task source given this's relevant global object to perform the following steps:

        1. If abortedDuringSummarization is true, then:

          1. Reject promise with options["signal"]'s abort reason.

          2. Abort these steps.

        2. If this's destroyed is true, then:

          1. Reject promise with this's destruction reason.

          2. Abort these steps.

        3. Resolve promise with summary.

    4. Let error be the following steps given summarization error information errorInfo:

      1. Queue a global task on the AI task source given this's relevant global object to perform the following steps:

        1. If abortedDuringSummarization is true, then:

          1. Reject promise with options["signal"]'s abort reason.

          2. Abort these steps.

        2. Let exception be the result of creating a DOMException with name given by errorInfo’s error name, using errorInfo’s error information to populate the message appropriately.

        3. Reject promise with exception.

    5. Let stopProducing be the following steps:

      1. Return abortedDuringSummarization.

    6. Summarize input given this's shared context, context, this's summary type, this's summary format, this's summary length, chunkProduced, done, error, and stopProducing.

  9. Return promise.

The summarizeStreaming(input, options) method steps are:
  1. If this's relevant global object is a Window whose associated Document is not fully active, then return a promise rejected with an "InvalidStateError" DOMException.

  2. If this's destroyed is true, then return a promise rejected with this's destruction reason.

  3. If options["signal"] exists and is aborted, then return a promise rejected with options["signal"]'s abort reason.

  4. Let abortedDuringSummarization be false.

    This variable tracks web developer aborts via the options["signal"] AbortSignal, which are surfaced as errors. It will be written to from the event loop, but sometimes read from in parallel.

  5. If options["signal"] exists, then add the following abort steps to options["signal"]:

    1. Set abortedDuringSummarization to true.

  6. Let stream be a new ReadableStream created in this's relevant realm.

  7. Let canceledDuringSummarization be false.

    This variable tracks web developer stream cancelations via stream.cancel(), which are not surfaced as errors. It will be written to from the event loop, but sometimes read from in parallel.

  8. Set up stream with cancelAlgorithm set to the following steps (ignoring the reason argument):

    1. Set canceledDuringSummarization to true.

  9. Let context be options["context"] if it exists; otherwise null.

  10. In parallel:

    1. Let chunkProduced be the following steps given a string chunk:

      1. Queue a global task on the AI task source given this's relevant global object to perform the following steps:

        1. If abortedDuringSummarization is true, then:

          1. Error stream with options["signal"]'s abort reason.

          2. Abort these steps.

        2. If this's destroyed is true, then:

          1. Error stream with this's destruction reason.

          2. Abort these steps.

        3. Enqueue chunk into stream.

    2. Let done be the following steps:

      1. Queue a global task on the AI task source given this's relevant global object to perform the following steps:

        1. If abortedDuringSummarization is true, then:

          1. Error stream with options["signal"]'s abort reason.

          2. Abort these steps.

        2. If this's destroyed is true, then:

          1. Error stream with this's destruction reason.

          2. Abort these steps.

        3. Close stream.

    3. Let error be the following steps given summarization error information errorInfo:

      1. Queue a global task on the AI task source given this's relevant global object to perform the following steps:

        1. If abortedDuringSummarization is true, then:

          1. Error stream with options["signal"]'s abort reason.

          2. Abort these steps.

        2. If this's destroyed is true, then:

          1. Error stream with this's destruction reason.

          2. Abort these steps.

        3. Let exception be the result of creating a DOMException with name given by errorInfo’s error name, using errorInfo’s error information to populate the message appropriately.

        4. Error stream with exception.

    4. Let stopProducing be the following steps:

      1. If any of abortedDuringSummarization, canceledDuringSummarization, or this's destroyed are true, then return true.

      2. Return false.

    5. Summarize input given this's shared context, context, this's summary type, this's summary format, this's summary length, chunkProduced, done, error, and stopProducing.

  11. Return stream.

To summarize a string input, given a string-or-null sharedContext, a string-or-null context, an AISummarizerType type, an AISummarizerFormat format, an AISummarizerLength length, 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 summarization error information and returns nothing, and an algorithm stopProducing that takes no arguments and returns a boolean:
  1. Assert: this algorithm is running in parallel.

  2. Assert: the current summarizer create options availability given type, format, and length is "readily".

    Otherwise, the AISummarizer object would not have been created.

  3. In an implementation-defined manner, subject to the following guidelines, begin the processs of summarizing input into a string.

    If they are non-null, sharedContext and context should be used to aid in the summarization by providing context on how the web developer wishes the input to be summarized.

    The summarization should conform to the guidance given by type, format, and length, in the definitions of each of their enumeration values.

  4. While true:

    1. Wait for the next chunk of summarization data to be produced, for the summarization process to finish, or for the result of calling stopProducing to become true.

    2. If such a chunk is successfully produced:

      1. Let it be represented as a string chunk.

      2. Perform chunkProduced given chunk.

    3. Otherwise, if the summarization process has finished:

      1. Perform done.

      2. Break.

    4. Otherwise, if stopProducing returns true, then break.

      The caller will handle signaling cancelation or aborting as necessary.

    5. Otherwise, if an error occurred during summarization:

      1. Let the error be represented as summarization error information errorInfo according to the guidance in § 3.5 Errors.

      2. Perform error given errorInfo.

      3. Break.


The destroy() method steps are to destroy this given a new "AbortError" DOMException.

To destroy an AISummarizer summarizer, given a JavaScript value reason:
  1. Set summarizer’s destroyed to true.

  2. Set summarizer’s destruction reason to reason.

  3. The user agent should release any resources associated with summarizer, such as AI models loaded during initialize the summarization model, as long as those resources are not needed for other ongoing operations.

3.4. Options

The summarize 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 AISummarizerType, AISummarizerFormat, and AISummarizerLength enumerations.

This section gives normative guidance on how the implementation of summarize should use each enumeration value to guide the summarization process.

AISummarizerType values
Value Meaning
"tl;dr"

The summary should be short and to the point, providing a quick overview of the input, suitable for a busy reader.

"teaser"

The summary should focus on the most interesting or intriguing parts of the input, designed to draw the reader in to read more.

"key-points"

The summary should extract the most important points from the input, presented as a bulleted list.

"headline"

The summary should effectively contain the main point of the input in a single sentence, in the format of an article headline.

AISummarizerLength values
Value Meaning
"short"

The guidance is dependent on the value of AISummarizerType:

"tl;dr"
"teaser"

The summary should fit within 1 sentence.

"key-points"

The summary should consist of no more than 3 bullet points.

"headline"

The summary should use no more than 12 words.

"medium"

The guidance is dependent on the value of AISummarizerType:

"tl;dr"
"teaser"

The summary should fit within 1 short paragraph.

"key-points"

The summary should consist of no more than 5 bullet points.

"headline"

The summary should use no more than 17 words.

"long"

The guidance is dependent on the value of AISummarizerType:

"tl;dr"
"teaser"

The summary should fit within 1 paragraph.

"key-points"

The summary should consist of no more than 7 bullet points.

"headline"

The summary should use no more than 22 words.

As with all "should"-level guidance, user agents might not conform perfectly to these. Especially in the case of counting words, it’s expected that language models might not conform perfectly.

AISummarizerFormat values
Value Meaning
"plain-text"

The summary should not contain any formatting or markup language.

"markdown"

The summary should be formatted using the Markdown markup language, ideally as valid CommonMark. [COMMONMARK]

3.5. Errors

A summarization error information is a struct with the following items:

error name

a string that will be used for the DOMException's name.

error information

other information necessary to create a useful DOMException for the web developer. (Typically, just an exception message.)

When summarization fails, the following possible reasons may be surfaced to the web developer. This table lists the possible DOMException names and the cases in which an implementation should use them:

DOMException name Scenarios
"NotAllowedError"

Summarization is disabled by user choice or user agent policy.

"NotReadableError"

The summarization output was filtered by the user agent, e.g., because it was detected to be harmful, inaccurate, or nonsensical.

"NotSupportedError"

The input to be summarized was in a language that the user agent does not support summarizing.

The summarization output was detected to be in a language that the user agent does not have sufficient quality control for and is not willing to support.

"QuotaExceededError"

The input to be summarized was too large for the user agent to handle.

"UnknownError"

All other scenarios, or if the user agent would prefer not to disclose the failure reason.

This table does not give the complete list of exceptions that can be surfaced by summarizer.summarize() and summarizer.summarizeStreaming(). It only contains those which can come from the implementation-defined summarize algorithm.

Index

Terms defined by this specification

Terms defined by reference

References

Normative References

[COMMONMARK]
CommonMark Spec. URL: https://spec.commonmark.org/
[DOM]
Anne van Kesteren. DOM Standard. Living Standard. URL: https://dom.spec.whatwg.org/
[ECMA-402]
ECMAScript Internationalization API Specification. URL: https://tc39.es/ecma402/
[HR-TIME-3]
Yoav Weiss. High Resolution Time. URL: https://w3c.github.io/hr-time/
[HTML]
Anne van Kesteren; et al. HTML Standard. Living Standard. URL: https://html.spec.whatwg.org/multipage/
[INFRA]
Anne van Kesteren; Domenic Denicola. Infra Standard. Living Standard. URL: https://infra.spec.whatwg.org/
[STREAMS]
Adam Rice; et al. Streams Standard. Living Standard. URL: https://streams.spec.whatwg.org/
[WEBIDL]
Edgar Chen; Timothy Gu. Web IDL Standard. Living Standard. URL: https://webidl.spec.whatwg.org/
[XHR]
Anne van Kesteren. XMLHttpRequest Standard. Living Standard. URL: https://xhr.spec.whatwg.org/

IDL Index

partial interface WindowOrWorkerGlobalScope {
  [Replaceable, SecureContext] readonly attribute AI ai;
};

[Exposed=(Window,Worker), SecureContext]
interface AI {};

[Exposed=(Window,Worker), SecureContext]
interface AICreateMonitor : EventTarget {
  attribute EventHandler ondownloadprogress;
};

callback AICreateMonitorCallback = undefined (AICreateMonitor monitor);

enum AICapabilityAvailability { "readily", "after-download", "no" };

partial interface AI {
  readonly attribute AISummarizerFactory summarizer;
};

[Exposed=(Window,Worker), SecureContext]
interface AISummarizerFactory {
  Promise<AISummarizer> create(optional AISummarizerCreateOptions options = {});
  Promise<AISummarizerCapabilities> capabilities();
};

[Exposed=(Window,Worker), SecureContext]
interface AISummarizer {
  Promise<DOMString> summarize(
    DOMString input,
    optional AISummarizerSummarizeOptions options = {}
  );
  ReadableStream summarizeStreaming(
    DOMString input,
    optional AISummarizerSummarizeOptions options = {}
  );

  readonly attribute DOMString sharedContext;
  readonly attribute AISummarizerType type;
  readonly attribute AISummarizerFormat format;
  readonly attribute AISummarizerLength length;

  undefined destroy();
};

[Exposed=(Window,Worker), SecureContext]
interface AISummarizerCapabilities {
  readonly attribute AICapabilityAvailability available;

  AICapabilityAvailability createOptionsAvailable(
    optional AISummarizerCreateCoreOptions options = {}
  );
  AICapabilityAvailability languageAvailable(DOMString languageTag);
};

dictionary AISummarizerCreateCoreOptions {
  AISummarizerType type = "key-points";
  AISummarizerFormat format = "markdown";
  AISummarizerLength length = "short";
};

dictionary AISummarizerCreateOptions : AISummarizerCreateCoreOptions {
  AbortSignal signal;
  AICreateMonitorCallback monitor;

  DOMString sharedContext;
};

dictionary AISummarizerSummarizeOptions {
  AbortSignal signal;
  DOMString context;
};

enum AISummarizerType { "tl;dr", "teaser", "key-points", "headline" };
enum AISummarizerFormat { "plain-text", "markdown" };
enum AISummarizerLength { "short", "medium", "long" };