diff --git a/index.bs b/index.bs index f1bcd63..a472c28 100644 --- a/index.bs +++ b/index.bs @@ -561,28 +561,105 @@ dictionary ModelContextRegisterToolOptions {

ModelContextClient Interface

-The {{ModelContextClient}} interface represents an [=agent=] executing a tool provided by the site through the {{ModelContext}} API. +The {{ModelContextClient}} interface represents an [=agent=] executing a tool provided by the site +through the {{ModelContext}} API. [Exposed=Window, SecureContext] interface ModelContextClient { - Promise<any> requestUserInteraction(UserInteractionCallback callback); + Promise<ModelContextUserInputResult> requestUserInput( + ModelContextUserInputOptions options, + optional ModelContextInteractiveCallback callback); }; -callback UserInteractionCallback = Promise<any> (); +callback ModelContextInteractiveCallback = Promise<any> (); + +enum ModelContextUserInputMode { "interactive", "form", "url" }; + +enum ModelContextUserInputAction { "accept", "decline", "cancel" }; + +dictionary ModelContextUserInputOptions { + required ModelContextUserInputMode mode; + USVString message; + object requestedSchema; + USVString url; + AbortSignal signal; +}; + +dictionary ModelContextUserInputResult { + required ModelContextUserInputAction action; + object content; +};
-
client.{{ModelContextClient/requestUserInteraction(callback)}}
+
result = await client.{{ModelContextClient/requestUserInput(options, callback)|requestUserInput}}({ mode: "interactive" }, callback)
+
+

Requests user input using an interactive in-page flow. If the [=agent=] currently has + exclusive control of the page (e.g. keyboard and mouse input are locked), then it yields control + so the user can interact with the page directly. The callback is invoked to perform the + interaction, and the promise resolves with the result of the callback wrapped in a + {{ModelContextUserInputResult}}. +

+ +
result = await client.{{ModelContextClient/requestUserInput(options, callback)|requestUserInput}}({ mode: "form", requestedSchema: { ... } })
-

Asynchronously requests user input during the execution of a tool. +

Requests structured input from the user via a form. The {{ModelContextUserInputOptions/requestedSchema}} + describes the data the tool needs as a JSON Schema [[!JSON-SCHEMA]] object. The [=agent=] + presents a form to the user through its own user interface, collects the information, and returns it to the tool. +

-

The callback function is invoked to perform the user interaction (e.g., showing a confirmation dialog), and the promise resolves with the result of the callback. +

result = await client.{{ModelContextClient/requestUserInput(options, callback)|requestUserInput}}({ mode: "url", url: "https://example.com/authenticate" })
+
+

Requests the user navigate to a URL for an out-of-band interaction. The [=agent=] presents + the URL to the user and the promise resolves with a {{ModelContextUserInputResult}} indicating whether the + user accepted, declined, or canceled the navigation prompt. This mode is intended for sensitive + flows (e.g., authentication, payment) where user-provided data must not flow through the + [=agent=]. The tool detects completion and retrieves data through out-of-band means (e.g., a site + backend callback).

+The {{ModelContextUserInputOptions}} dictionary configures the elicitation request: + +
+ : mode + :: The elicitation mode. One of "{{ModelContextUserInputMode/interactive}}", "{{ModelContextUserInputMode/form}}", or + "{{ModelContextUserInputMode/url}}". + + : message + :: A human-readable message explaining why the interaction is needed. The [=agent=] may surface + this to the user, or provide a reasonable default if omitted (e.g., "example.com needs your input"). + + : requestedSchema + :: A JSON Schema [[!JSON-SCHEMA]] object describing the structure of the expected response. Only + used in "{{ModelContextUserInputMode/form}}" mode. The schema is restricted to flat objects with primitive + properties (string, number, integer, boolean, and enum) to simplify form rendering. + + : url + :: The URL the user should navigate to. Required for "{{ModelContextUserInputMode/url}}" mode. + + : signal + :: An {{AbortSignal}} that aborts the pending request when triggered. +
+ +The {{ModelContextUserInputResult}} dictionary describes the outcome of a user input request: + +
+ : action + :: The user's response action: + - "{{ModelContextUserInputAction/accept}}": The user provided the requested input. + - "{{ModelContextUserInputAction/decline}}": The user explicitly declined the request. + - "{{ModelContextUserInputAction/cancel}}": The request was dismissed or timed out. + + : content + :: The user-provided data. Present when {{ModelContextUserInputResult/action}} is "{{ModelContextUserInputAction/accept}}" + and the mode is "{{ModelContextUserInputMode/interactive}}" or "{{ModelContextUserInputMode/form}}". For + "{{ModelContextUserInputMode/url}}" mode, data is exchanged out-of-band and this field is not used. +
+
-The requestUserInteraction(callback) method steps are: +The requestUserInput(options, callback) method steps are: 1. TODO: fill this out.