diff --git a/index.bs b/index.bs
index 51e4d09..8669a88 100644
--- a/index.bs
+++ b/index.bs
@@ -794,8 +794,7 @@ The registerTool(tool, optionsgetTools(options) method steps
1. Run the following steps [=in parallel=]:
- 1. Let |tools| be an empty [=list=] of {{RegisteredTool}} dictionaries.
+ 1. Let |discoveredTools| be an empty [=list=].
1. Let |navigables| be |toolRequestor|'s [=node navigable=]'s [=navigable/traversable
navigable=]'s [=navigable/active document=]'s [=Document/inclusive descendant navigables=].
@@ -917,6 +916,15 @@ The getTools(options) method steps
definition/exposed origins=], and |callerOrigin| returns false, then
[=iteration/continue=].
+ 1. [=list/Append=] (|tool definition|, |targetDocument|) to |discoveredTools|.
+
+ 1. [=Queue a global task=] on the [=webmcp task source=] given |global| to run the following
+ steps:
+
+ 1. Let |tools| be an empty [=list=] of {{RegisteredTool}} dictionaries.
+
+ 1. [=list/For each=] (|tool definition|, |targetDocument|) of |discoveredTools|:
+
1. Let |registeredTool| be a new {{RegisteredTool}} dictionary, with the following fields:
: {{RegisteredTool/name}}
@@ -934,8 +942,8 @@ The getTools(options) method steps
: {{RegisteredTool/inputSchema}}
:: the result of [=parse a JSON string to a JavaScript value=] given |tool
- definition|'s [=tool definition/input schema=], if |tool definition|'s [=tool
- definition/input schema=] is not the empty string; otherwise undefined.
+ definition|'s [=tool definition/input schema=], if |tool definition|'s
+ [=tool definition/input schema=] is not the empty string; otherwise undefined.
Note: This will never throw an exception, because the string stored in the tool
definition is always a valid JSON string.
@@ -944,7 +952,7 @@ The getTools(options) method steps
:: |targetDocument|'s [=relevant global object=]
: {{RegisteredTool/origin}}
- :: |targetOrigin|, [=serialization of an origin|serialized=].
+ :: [=serialization of an origin|serialized=] |targetDocument|'s [=Document/origin=].
: {{RegisteredTool/annotations}}
:: if |tool definition|'s [=tool definition/annotations=] is not null, a
@@ -959,11 +967,10 @@ The getTools(options) method steps
1. [=list/Append=] |registeredTool| to |tools|.
- 1. [=list/Sort in ascending order=] |tools|, with |a| being less than |b| if
- |a|["{{RegisteredTool/name}}"] is [=code unit less than=] |b|["{{RegisteredTool/name}}"].
+ 1. [=list/Sort in ascending order=] |tools|, with |a| being less than |b| if
+ |a|["{{RegisteredTool/name}}"] is [=code unit less than=] |b|["{{RegisteredTool/name}}"].
- 1. [=Queue a global task=] on the [=webmcp task source=] given |global| to [=resolve=] |promise|
- with |tools|.
+ 1. [=Resolve=] |promise| with |tools|.
1. Return |promise|.
@@ -1008,6 +1015,9 @@ The executeTool(tool, inputObject
1. Let |targetDocument| be |targetWindow|'s [=associated Document|associated
Document=].
+1. If |targetDocument|'s [=node navigable=] is null, then return [=a promise rejected with=] an
+ "{{InvalidStateError}}" {{DOMException}}.
+
1. Let |uuid| be a new [=unique internal value=].
1. If |options|'s {{ModelContextExecuteToolOptions/signal}} [=map/exists=], then:
@@ -1490,6 +1500,11 @@ steps:
ModelContext=]'s [=ModelContext/internal context=]'s [=model context/tool
map=]'s [=map/values=], which are [=tool definitions=].
+ Note: Although these steps run on the [=AI agent queue=] [=in parallel=] with each
+ {{Document}}'s [=relevant agent=]'s [=agent/event loop=], implementations synchronize
+ access to each [=model context/tool map=] via inter-process communication or locking so that
+ partial updates are never observed.
+
1. Let |observedToolCollection| be a new [=observed tool collection=] with the following [=struct/items=]:
: [=observed tool collection/origin=]