diff --git a/index.bs b/index.bs index 48c44a1..13081bf 100644 --- a/index.bs +++ b/index.bs @@ -164,10 +164,9 @@ A tool definition is a [=struct=] with the following [=struct/items=] [[!JSON-SCHEMA]] : execute steps - :: a set of steps to invoke the tool. + :: an algorithm that takes both a [=string=] and an algorithm completionSteps that itself takes a [=string=]-or-null and a [=boolean=]. - Note: For tools registered imperatively, these steps will simply invoke the supplied - {{ToolExecuteCallback}} callback. For tools registered + Note: For tools registered imperatively, these steps will simply invoke the [=imperative execute steps=]. For tools registered [declaratively](https://github.com/webmachinelearning/webmcp/pull/76), this will be a set of "internal" steps that have not been defined yet, that describe how to fill out a <{form}> and its [=form-associated elements=]. @@ -257,6 +256,38 @@ a [=list=] of [=origins=] |exposed origins|, and an [=origin=] |accessing origin +
toolactivated" event.
+
+1. Let |toolPromise| be the result of [=invoke|invoking=] |tool|'s {{ModelContextTool/execute}} with
+ |inputObject|.
+
+1. [=promise/React=] to |toolPromise|:
+
+ - If |toolPromise| was fulfilled with value |v|:
+
+ 1. Let |serializedResult| be the result of [=serializing a JavaScript value to a JSON string=] given |v|. If this throws an exception, run |completionSteps| given null and false, and abort these steps.
+
+ 1. Run |completionSteps| given |serializedResult| and true.
+
+ - If |toolPromise| was rejected with reason r, then run |completionSteps| given null and false.
+
+document.{{Document/modelContext}}.{{ModelContext/executeTool(tool, inputArguments, options)}}Executes a tool on the document it was registered on. Returns a promise that resolves to the + result of the tool's execution.
+Document=].
+
+1. If |invokingDocument| is not [=Document/fully active=], then return [=a promise rejected with=]
+ an "{{InvalidStateError}}" {{DOMException}}.
+
+1. If this's [=surrounding agent=]'s [=agent cluster=]'s [=is origin-keyed=] is false and this's
+ [=relevant settings object=]'s [=environment settings object/origin=]'s [=origin/scheme=] is not
+ "file", then return [=a promise rejected with=] a "{{SecurityError}}"
+ {{DOMException}}.
+
+1. If |invokingDocument| is not [=allowed to use=] the "{{tools}}" feature, then return [=a promise
+ rejected with=] a "{{NotAllowedError}}" {{DOMException}}.
+
+1. Let |expectedTargetOriginURL| be the result of [=URL parser|parsing=] |tool|'s
+ {{RegisteredTool/origin}}.
+
+1. If |expectedTargetOriginURL| is failure, then return [=a promise rejected with=] a
+ "{{DataError}}" {{DOMException}}.
+
+1. Let |expectedTargetOrigin| be |expectedTargetOriginURL|'s [=url/origin=].
+
+1. [=Assert=]: |expectedTargetOrigin| is not an [=opaque origin=].
+
+1. Let |promise| be [=a new promise=] created in [=this=]'s [=relevant realm=].
+
+1. Let |signal| be |options|'s {{ExecuteToolOptions/signal}} if it [=map/exists=]; otherwise null.
+
+1. If |signal| is not null, then:
+
+ 1. If |signal| is [=AbortSignal/aborted=], then return [=a promise rejected with=] |signal|'s
+ [=AbortSignal/abort reason=].
+
+ 1. [=AbortSignal/add|Add the following abort steps=] to |signal|:
+
+ 1. [=Reject=] |promise| with |signal|'s [=AbortSignal/abort reason=].
+
+ Issue(#48): Wire up |signal| to the tool execution callback in the tool host's document, so that tool abort is communicated all the way through.
+
+1. Let |targetWindow| be |tool|'s {{RegisteredTool/window}}.
+
+1. Let |targetDocument| be |targetWindow|'s [=associated Document|associated
+ Document=].
+
+1. Run the following steps [=in parallel=]:
+
+ 1. If |targetDocument|'s [=node navigable=]'s [=navigable/traversable navigable=] is not
+ |invokingDocument|'s [=node navigable=]'s [=navigable/traversable navigable=], then [=queue a
+ global task=] on the [=webmcp task source=] given |invokingDocument|'s [=relevant global
+ object=] to [=reject=] |promise| with an "{{UnknownError}}" {{DOMException}}, and abort these
+ steps.
+
+ 1. Let |targetOrigin| be |targetDocument|'s [=Document/origin=].
+
+ 1. Let |callerOrigin| be |invokingDocument|'s [=Document/origin=].
+
+ 1. If |targetOrigin| is not [=same origin=] with |expectedTargetOrigin|, then [=queue a global
+ task=] on the [=webmcp task source=] given |invokingDocument|'s [=relevant global object=] to
+ [=reject=] |promise| with an "{{UnknownError}}" {{DOMException}}, and abort these steps.
+
+ Issue: Support more granular errors than "{{UnknownError}}", based on each failure case.
+
+ 1. Let |targetToolMap| be |targetDocument|'s [=Document/associated ModelContext|associated
+ ModelContext=]'s [=ModelContext/internal context=]'s [=model context/tool map=].
+
+ 1. Let |toolName| be |tool|'s {{RegisteredTool/name}}.
+
+ 1. If |targetToolMap|[|toolName|] does not [=map/exist=], then [=queue a global task=] on the
+ [=webmcp task source=] given |invokingDocument|'s [=relevant global object=] to [=reject=]
+ |promise| with an "{{UnknownError}}" {{DOMException}}, and abort these steps.
+
+ Issue: Support more granular errors than "{{UnknownError}}", based on each failure case.
+
+ 1. Let |tool definition| be |targetToolMap|[|toolName|].
+
+ 1. If [=tool is exposed to an origin=] given |targetOrigin|, |tool definition|'s [=tool
+ definition/exposed origins=], and |callerOrigin| is false, then [=queue a global task=] on the
+ [=webmcp task source=] given |invokingDocument|'s [=relevant global object=] to [=reject=]
+ |promise| with an "{{UnknownError}}" {{DOMException}}, and abort these steps.
+
+ Issue: Support more granular errors than "{{UnknownError}}", based on each failure case.
+
+ 1. Let |completionSteps| be an algorithm that takes a [=string=]-or-null |result| and a [=boolean=] |success|, and runs the following steps:
+
+ 1. [=Assert=]: these steps are running [=in parallel=].
+
+ 1. If |success| is true, then [=queue a global task=] on the [=webmcp task source=] given |invokingDocument|'s [=relevant global object=] to [=resolve=] |promise| with |result|.
+
+ 1. Otherwise, [=queue a global task=] on the [=webmcp task source=] given |invokingDocument|'s [=relevant global object=] to [=reject=] |promise| with an "{{UnknownError}}" {{DOMException}}.
+
+ 1. [=Queue a global task=] on the [=webmcp task source=] given |targetWindow| to run |tool
+ definition|'s [=tool definition/execute steps=] given |inputArguments| and |completionSteps|.
+
+1. Return |promise|.
+
+tool["{{ModelContextTool/name}}"]A unique identifier for the tool. This is used by [=agents=] to reference the tool when making tool calls. +
A unique identifier for the tool. This is used by [=agents=] to reference the tool when + making tool calls.
tool["{{ModelContextTool/title}}"]A label for the tool. This is used by the user agent to reference the tool in the user interface. -
It is recommended that this string be localized to the user's -{{NavigatorLanguage/language}}. +
A label for the tool. This is used by the user agent to reference the tool in the user + interface.
It is recommended that this string be localized to the user's + {{NavigatorLanguage/language}}.
tool["{{ModelContextTool/description}}"]A natural language description of the tool's functionality. This helps [=agents=] understand when and how to use the tool. +
A natural language description of the tool's functionality. This helps [=agents=] understand + when and how to use the tool.
tool["{{ModelContextTool/inputSchema}}"]options["{{ExecuteToolOptions/signal}}"]
+ :: An {{AbortSignal}} that can be used to cancel the execution of the tool.
+