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 +
+The imperative execute steps, given a {{ModelContextTool}} |tool|, a {{Window}} +|targetWindow|, a [=string=] |inputArguments|, and an algorithm |completionSteps|, are as follows: + +1. [=Assert=]: these steps are running on |targetWindow|'s [=relevant agent=]'s [=agent/event + loop=]. + +1. Let |inputObject| be the result of [=parse a JSON string to a JavaScript value=] given + |inputArguments| and |targetWindow|'s [=relevant realm=]. If exception was thrown, then + run |completionSteps| given null and false, and abort these steps. + + Issue: Support more granular errors; here we should return something that prompts the caller to reject its {{Promise}} with a "{{DataError}}" {{DOMException}}. + +1. If |inputObject| [=Object type|is not an Object=] is false, then run |completionSteps| given null and false, and abort these steps. + + Issue(#146): Specify and fire the "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. + +
+
To unregister a tool given a {{ModelContext}} |modelContext| and a [=string=] |tool name|, run these steps: @@ -323,6 +354,7 @@ The {{ModelContext}} interface provides methods for web applications to register interface ModelContext : EventTarget { Promise registerTool(ModelContextTool tool, optional ModelContextRegisterToolOptions options = {}); Promise> getTools(optional ModelContextGetToolOptions options = {}); + Promise executeTool(RegisteredTool tool, DOMString inputArguments, optional ExecuteToolOptions options = {}); attribute EventHandler ontoolchange; }; @@ -348,6 +380,12 @@ is a [=model context=] [=struct=] created alongside the {{ModelContext}}. agents written in JavaScript, and possibly living in <{iframe}>s. The [=user agent=]'s [=browser agent=] uses a different internal mechanism to retrieve the tools exposed to it.

+ +
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.

+
@@ -451,7 +489,8 @@ The registerTool(tool, optionsregisterTool(tool, optionsgetTools(options) method steps
+
+The executeTool(tool, inputArguments, +options) method steps are: + +1. Let |invokingDocument| be [=this=]'s [=relevant global object=]'s [=associated + Document|associated 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|. + +
+

ModelContextTool Dictionary

The {{ModelContextTool}} dictionary describes a tool that can be invoked by [=agents=]. @@ -617,19 +757,21 @@ callback ToolExecuteCallback = Promise (object input);
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}}"]
@@ -700,6 +842,22 @@ dictionary ModelContextGetToolOptions { same-origin documents.
+

ExecuteToolOptions Dictionary

+ +The {{ExecuteToolOptions}} dictionary allows web applications to pass options to +{{ModelContext/executeTool()}}. + + +dictionary ExecuteToolOptions { + AbortSignal signal; +}; + + +
+ : options["{{ExecuteToolOptions/signal}}"] + :: An {{AbortSignal}} that can be used to cancel the execution of the tool. +
+

RegisteredTool Dictionary

The {{RegisteredTool}} dictionary represents a tool that has been registered and is available for