diff --git a/index.bs b/index.bs index 847677e..62e7dd1 100644 --- a/index.bs +++ b/index.bs @@ -190,6 +190,9 @@ A model context is a [=struct=] with the following [=struct/items=]: object's event loop, and because it is event-loop-local, it can get out of sync from the [=traversable navigable=]'s more "global" map. + : pending tool readiness promises + :: a [=set=] of {{Promise}} objects, initially empty. + A tool definition is a [=struct=] with the following [=struct/items=]: @@ -500,6 +503,64 @@ a [=list=] of [=origins=] |exposed origins|, and an [=origin=] |accessing origin +
ModelContext=]'s [=ModelContext/internal context=].
+
+1. Set |document|'s [=Document/tools-ready=] to true if |context|'s [=model context/pending tool
+ readiness promises=] is [=set/is empty|empty=]; otherwise false.
+
+ready" or "abort", run these steps:
+
+1. [=Assert=]: these steps are running [=in parallel=].
+
+1. Let |activeDocument| be |traversable|'s [=navigable/active document=].
+
+1. [=Assert=]: |activeDocument| is [=Document/fully active=].
+
+1. Let |areAllReady| be an algorithm that returns a [=boolean=] by running these steps:
+
+ 1. If |activeDocument| is not [=Document/fully active=], then return true.
+
+ Note: If |activeDocument| becomes inactive while waiting (for example, because |traversable|
+ navigated or was destroyed), returning true here immediately unblocks the wait.
+
+ 1. [=list/For each=] [=navigable=] |navigable| of |activeDocument|'s [=Document/inclusive
+ descendant navigables=]:
+
+ 1. Let |document| be |navigable|'s [=navigable/active document=].
+
+ 1. If |document|'s [=Document/tools-ready=] is false, then return false.
+
+ Note: Although [=Document/tools-ready=] is modified on |document|'s [=relevant agent=]'s
+ [=agent/event loop=] and read here [=in parallel=], implementations synchronize updates to
+ [=Document/tools-ready=] (for example, via inter-process communication to the browser
+ process) ordered with updates to [=model context/tool map=].
+
+ 1. Return true.
+
+1. If the result of running |areAllReady| is false, then wait until either the result of running
+ |areAllReady| is true, or an [=implementation-defined=] timeout has elapsed since this step
+ began.
+
+ Note: The timeout is measured from when this wait begins. Calling
+ {{ModelContext/waitForToolsUntil()}} with additional promises while a wait is already in progress
+ does not reset or extend the timeout, and calling it after |areAllReady| returns true does not
+ delay an operation that has already been unblocked.
+
+1. Return "ready" if |activeDocument| is [=Document/fully active=]; otherwise
+ "abort".
+
+ModelContext=] must be set to a [=new=] {{ModelContext}} object created in the
{{Document}}'s [=relevant realm=].
+Each {{Document}} object has a tools-ready [=boolean=], initially true.
+
+Issue(#328): [=Document/tools-ready=] should be false when the {{Document}} is created, unless the
+{{Document}} is not [=allowed to use=] the "{{tools}}" feature. This gives authors an opportunity to
+use {{ModelContext/waitForToolsUntil()}} until a deterministic {{Document}} lifecycle point. The
+exact lifecycle point still needs to be resolved.
+
document.{{Document/modelContext}}.{{ModelContext/toolsReady}}Returns true if the document's tools are ready to be read.
+document.{{Document/modelContext}}.{{ModelContext/registerTool(tool, options)}}Registers a tool that [=agents=] can invoke. Returns a rejected promise if a tool with the @@ -750,6 +826,14 @@ is a [=model context=] [=struct=] created alongside the {{ModelContext}}. or {{ModelContextTool/outputSchema}} is invalid.
document.{{Document/modelContext}}.{{ModelContext/waitForToolsUntil(promise)}}Signals that the document is asynchronously registering or updating its tools, and that tool + consumers should wait until promise settles (or a timeout elapses) before + reading the document's tools. Multiple promises can be registered; the document's tools are + considered ready once all registered promises have settled.
+document.{{Document/modelContext}}.{{ModelContext/getTools(options)}}Returns a promise that resolves to a list of registered tools from this document and its @@ -784,6 +868,33 @@ is a [=model context=] [=struct=] created alongside the {{ModelContext}}. ```
Document=]'s [=Document/tools-ready=].
+
+Document=].
+
+1. If |document| is not [=Document/fully active=], then [=exception/throw=] an "{{InvalidStateError}}"
+ {{DOMException}}.
+
+1. If |document| is not [=allowed to use=] the "{{tools}}" feature, then [=exception/throw=] a
+ "{{NotAllowedError}}" {{DOMException}}.
+
+1. If |promise|.\[[Promise]].\[[PromiseState]] is not `pending`, then:
+
+ 1. If |promise|.\[[Promise]].\[[PromiseState]] is `rejected`, then [=mark as handled|mark=]
+ |promise| as handled.
+
+ Note: When |promise| is `pending`, [=promise/react|reacting=] to it in the steps below marks
+ it as handled. If it is already `rejected` when passed in, returning early skips
+ [=promise/react=], so we explicitly mark it as handled here to prevent an
+ `unhandledrejection` event from firing.
+
+ 1. Return.
+
+1. Let |context| be [=this=]'s [=ModelContext/internal context=].
+
+1. [=set/Append=] |promise| to |context|'s [=model context/pending tool readiness promises=].
+
+1. [=Update the tools-ready state=] given |document|.
+
+1. Let |settleSteps| be the following steps:
+
+ 1. [=set/Remove=] |promise| from |context|'s [=model context/pending tool readiness
+ promises=].
+
+ 1. [=Update the tools-ready state=] given |document|.
+
+1. [=promise/React=] to |promise|:
+
+ - If |promise| was fulfilled, then run |settleSteps|.
+
+ - If |promise| was rejected, then run |settleSteps|.
+
+abort", then return.
+
+ Note: This happens if |traversable| navigated to a new {{Document}} or was destroyed while
+ waiting. In the navigation case, implementations will typically [=perform an observation=]
+ again for the new [=navigable/active document=].
+
1. Let |observation| be a new [=observation=].
1. Let |flat descendants| be the [=Document/inclusive descendant navigables=] of |traversable|'s
@@ -1633,6 +1797,11 @@ observation=] given any [=top-level browsing context=] in the [=user agent=] [=b
group set=], at any time, although implementations typically reserve this operation for when the
user is interacting with a [=browser agent=] while web content is in view.
+Note: Calling {{ModelContext/waitForToolsUntil()}} only delays [=observations=] that the [=user
+agent=] chooses to perform while a {{Document}}'s [=Document/tools-ready=] is false. Toggling
+[=Document/tools-ready=] does not by itself cause or guarantee that the [=user agent=] will
+[=perform an observation=].
+