diff --git a/index.bs b/index.bs index b72f33f..d0677b9 100644 --- a/index.bs +++ b/index.bs @@ -142,6 +142,78 @@ typedef ( ) LanguageModelMessageValue; +

Prompt processing

+ +

This will be incorporated into a proper part of the specification later. For now, we're just writing out this algorithm as a full spec, since it's complicated.

+ +
+ To validate and canonicalize a prompt given a {{LanguageModelPrompt}} |input|, a [=list=] of {{LanguageModelMessageType}}s |expectedTypes|, and a boolean |isInitial|, perform the following steps. The return value will be a non-empty [=list=] of {{LanguageModelMessage}}s in their "longhand" form. + + 1. [=Assert=]: |expectedTypes| [=list/contains=] "{{LanguageModelMessageType/text}}". + + 1. If |input| is a [=string=], then return « + «[ + "{{LanguageModelMessage/role}}" → "{{LanguageModelMessageRole/user}}", + "{{LanguageModelMessage/content}}" → « + «[ + "{{LanguageModelMessageContent/type}}" → "{{LanguageModelMessageType/text}}", + "{{LanguageModelMessageContent/value}}" → |input|     + ]» + » + ]» + ». + + 1. [=Assert=]: |input| is a [=list=] of {{LanguageModelMessage}}s. + + 1. Let |seenNonSystemRole| be false. + + 1. Let |messages| be an empty [=list=] of {{LanguageModelMessage}}s. + + 1. [=list/For each=] |message| of |input|: + + 1. If |message|["{{LanguageModelMessage/content}}"] is a [=string=], then set |message| to «[ + "{{LanguageModelMessage/role}}" → |message|["{{LanguageModelMessage/role}}"], + "{{LanguageModelMessage/content}}" → « + «[ + "{{LanguageModelMessageContent/type}}" → "{{LanguageModelMessageType/text}}", + "{{LanguageModelMessageContent/value}}" → |message|     + ]» + » + ]» to |messages|. + + 1. [=list/For each=] |content| of |message|["{{LanguageModelMessage/content}}"]: + + 1. If |message|["{{LanguageModelMessage/role}}"] is "{{LanguageModelMessageRole/system}}", then: + + 1. If |isInitial| is false, then throw a "{{NotSupportedError}}" {{DOMException}}. + + 1. If |seenNonSystemRole| is true, then throw a "{{SyntaxError}}" {{DOMException}}. + + 1. If |message|["{{LanguageModelMessage/role}}"] is not "{{LanguageModelMessageRole/system}}", then set |seenNonSystemRole| to true. + + 1. If |message|["{{LanguageModelMessage/role}}"] is "{{LanguageModelMessageRole/assistant}}" and |content|["{{LanguageModelMessageContent/type}}"] is not "{{LanguageModelMessageType/text}}", then throw a "{{NotSupportedError}}" {{DOMException}}. + + 1. If |content|["{{LanguageModelMessageContent/type}}"] is "{{LanguageModelMessageType/text}}" and |content|["{{LanguageModelMessageContent/value}}"] is not a [=string=], then throw a {{TypeError}}. + + 1. If |content|["{{LanguageModelMessageContent/type}}"] is "{{LanguageModelMessageType/image}}", then: + + 1. If |expectedTypes| does not [=list/contain=] "{{LanguageModelMessageType/image}}", then throw a "{{NotSupportedError}}" {{DOMException}}. + + 1. If |content|["{{LanguageModelMessageContent/value}}"] is not an {{ImageBitmapSource}} or {{BufferSource}}, then throw a {{TypeError}}. + + 1. If |content|["{{LanguageModelMessageContent/type}}"] is "{{LanguageModelMessageType/audio}}", then: + + 1. If |expectedTypes| does not [=list/contain=] "{{LanguageModelMessageType/audio}}", then throw a "{{NotSupportedError}}" {{DOMException}}. + + 1. If |content|["{{LanguageModelMessageContent/value}}"] is not an {{AudioBuffer}}, {{BufferSource}}, or {{Blob}}, then throw a {{TypeError}}. + + 1. [=list/Append=] |message| to |messages|. + + 1. If |messages| [=list/is empty=], then throw a "{{SyntaxError}}" {{DOMException}}. + + 1. Return |messages|. +
+

Permissions policy integration

Access to the prompt API is gated behind the [=policy-controlled feature=] "language-model", which has a [=policy-controlled feature/default allowlist=] of [=default allowlist/'self'=].