@jini-ai/agentic 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (62) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/dist/core/annotated-actions-script.d.ts +13 -0
  3. package/dist/core/annotated-actions-script.js +137 -0
  4. package/dist/core/index.d.ts +1 -0
  5. package/dist/core/index.js +1 -0
  6. package/package.json +2 -2
  7. package/dist/a2ui/agent-to-renderer.d.ts +0 -613
  8. package/dist/a2ui/agent-to-renderer.js +0 -191
  9. package/dist/a2ui/catalog.d.ts +0 -73
  10. package/dist/a2ui/catalog.js +0 -304
  11. package/dist/a2ui/common-types.d.ts +0 -401
  12. package/dist/a2ui/common-types.js +0 -130
  13. package/dist/a2ui/index.d.ts +0 -16
  14. package/dist/a2ui/index.js +0 -16
  15. package/dist/a2ui/interpreter.d.ts +0 -71
  16. package/dist/a2ui/interpreter.js +0 -337
  17. package/dist/a2ui/json-pointer.d.ts +0 -48
  18. package/dist/a2ui/json-pointer.js +0 -174
  19. package/dist/a2ui/renderer-to-agent.d.ts +0 -342
  20. package/dist/a2ui/renderer-to-agent.js +0 -111
  21. package/dist/a2ui/resolve.d.ts +0 -28
  22. package/dist/a2ui/resolve.js +0 -144
  23. package/dist/a2ui/tree.d.ts +0 -66
  24. package/dist/a2ui/tree.js +0 -74
  25. package/dist/ag-ui.d.ts +0 -82
  26. package/dist/ag-ui.js +0 -85
  27. package/dist/agui/encoder.d.ts +0 -50
  28. package/dist/agui/encoder.js +0 -97
  29. package/dist/agui/events.d.ts +0 -59
  30. package/dist/agui/events.js +0 -15
  31. package/dist/capability.d.ts +0 -81
  32. package/dist/capability.js +0 -79
  33. package/dist/dom/dom-page-driver.d.ts +0 -36
  34. package/dist/dom/dom-page-driver.js +0 -601
  35. package/dist/dom/index.d.ts +0 -17
  36. package/dist/dom/index.js +0 -17
  37. package/dist/dom/model-context.d.ts +0 -69
  38. package/dist/dom/model-context.js +0 -44
  39. package/dist/element-handles.d.ts +0 -120
  40. package/dist/element-handles.js +0 -39
  41. package/dist/gen-ui/encoder.d.ts +0 -50
  42. package/dist/gen-ui/encoder.js +0 -97
  43. package/dist/gen-ui/events.d.ts +0 -59
  44. package/dist/gen-ui/events.js +0 -15
  45. package/dist/gen-ui/index.d.ts +0 -18
  46. package/dist/gen-ui/index.js +0 -17
  47. package/dist/guards.d.ts +0 -96
  48. package/dist/guards.js +0 -186
  49. package/dist/handle.d.ts +0 -41
  50. package/dist/handle.js +0 -41
  51. package/dist/mcp-ui-apps.d.ts +0 -223
  52. package/dist/mcp-ui-apps.js +0 -252
  53. package/dist/mcp-ui.d.ts +0 -133
  54. package/dist/mcp-ui.js +0 -134
  55. package/dist/page-capabilities.d.ts +0 -14
  56. package/dist/page-capabilities.js +0 -129
  57. package/dist/page-driver.d.ts +0 -120
  58. package/dist/page-driver.js +0 -2
  59. package/dist/page-executor.d.ts +0 -94
  60. package/dist/page-executor.js +0 -320
  61. package/dist/webmcp.d.ts +0 -202
  62. package/dist/webmcp.js +0 -173
package/dist/webmcp.d.ts DELETED
@@ -1,202 +0,0 @@
1
- /**
2
- * @module webmcp
3
- *
4
- * Projection: {@link CapabilityDef} → a WebMCP tool registration.
5
- *
6
- * WebMCP (`document.modelContext.registerTool`) is the browser API by which a *page* offers
7
- * tools to an agent running inside the browser. It is a W3C Community Group draft, not a
8
- * standards-track spec, and it moves: the API relocated from `navigator.modelContext` to
9
- * `document.modelContext` on 2026-07-21, Chrome 150 deprecated the `navigator` location while
10
- * still serving it during the origin trial (Chrome 149–156), Edge ships it behind a flag, and
11
- * Firefox and Safari have made no commitment. Feature detection must therefore check `document`
12
- * first and fall back to `navigator`.
13
- *
14
- * That detection is deliberately NOT here: it touches browser globals, and this package holds
15
- * none. Framework bindings own host access; this file owns only the shape translation, so when
16
- * the registration shape changes again there is exactly one place to change it.
17
- *
18
- * Re-verified 2026-07-28 against the primary spec source
19
- * (https://webmachinelearning.github.io/webmcp/, `index.bs`). Four real gaps closed this pass,
20
- * all additive — none change the confirmation gate below, which is Jini's own addition and has
21
- * no spec counterpart:
22
- *
23
- * 1. **`signal`/`exposedTo`** — `ModelContextRegisterToolOptions`, the *second* positional
24
- * argument to `registerTool(tool, options)`. `signal` is the spec's ONLY unregistration
25
- * mechanism (there is no `unregisterTool()`); aborting it removes the tool and fires
26
- * `toolchange`. `exposedTo` scopes which cross-origin documents in the same tree may see the
27
- * tool. Neither belongs on the `ModelContextTool` dict itself, so they are not fields of
28
- * {@link WebMcpToolRegistration} — they ride along on its optional `registerOptions`, computed
29
- * from {@link ToWebMcpToolOptions}, so a caller has exactly one object to destructure:
30
- * `modelContext.registerTool(reg, reg.registerOptions)`.
31
- * 2. **`title`/`annotations`** — real `ModelContextTool` dict fields (`USVString title`,
32
- * `ToolAnnotations annotations`), now on {@link WebMcpToolRegistration}. `annotations.readOnlyHint`
33
- * defaults from {@link CapabilityDef.risk} (`'read'` → `true`) since Jini's manifests already
34
- * carry that judgment; a caller may override or add `untrustedContentHint` via `options.annotations`.
35
- * 3. **Tool name validation** — the spec's `registerTool` algorithm rejects (with an
36
- * `InvalidStateError` `DOMException`) a name that is empty, over 128 code points, or contains
37
- * anything outside ASCII alphanumeric plus `_`, `-`, `.`. `capability.id` becomes `name`
38
- * verbatim, so a malformed manifest entry previously surfaced as a cryptic browser-side
39
- * rejection days later; {@link toWebMcpTool} now checks it at projection time and names the
40
- * offending capability.
41
- * 4. **Schema-on-error** — WebMCP defines no input validation of its own (the spec's
42
- * `ToolExecuteCallback` is just `Promise<any> (object input)`), and this module's own doc used
43
- * to say so ("the caller is responsible for validating it... WebMCP does not"). That left a
44
- * wrong-schema call to fail deep inside whatever `execute` does, with no way for the caller to
45
- * self-correct in the same turn. `execute` now runs the manifest's own
46
- * {@link findCapabilityInputError} first and, on failure, throws the same
47
- * `"<id>: <reason>. Expected input: <schema>"` shape `page-executor.ts` already uses for
48
- * `page.*` — one discipline, not two.
49
- */
50
- import { type CapabilityDef, type CapabilityInputSchema } from './capability.js';
51
- /** The registration object `registerTool` accepts. WebMCP names the schema field `inputSchema`. */
52
- export interface WebMcpToolRegistration {
53
- readonly name: string;
54
- /**
55
- * `ModelContextTool.title` — an optional human-readable label, distinct from `name` (the
56
- * machine identifier) and `description` (what an agent reads to decide whether to call it). The
57
- * spec recommends localizing it to the user's language; this projection makes no attempt at
58
- * that; a caller wanting a localized title supplies it via `options.title`.
59
- */
60
- readonly title?: string;
61
- readonly description: string;
62
- readonly inputSchema: CapabilityInputSchema;
63
- readonly execute: (args: Record<string, unknown>) => Promise<unknown>;
64
- /** `ModelContextTool.annotations` — behavior hints. See {@link WebMcpToolAnnotations}. */
65
- readonly annotations?: WebMcpToolAnnotations;
66
- /**
67
- * The SECOND positional argument `registerTool(tool, options)` expects — the spec's
68
- * `ModelContextRegisterToolOptions`, not part of the `ModelContextTool` dict this object
69
- * otherwise models. Present only when `options.signal` or `options.exposedTo` was supplied.
70
- * Bundled here rather than returned as a second value so `toWebMcpTool`'s output stays a single
71
- * object a caller can pass straight through: `modelContext.registerTool(reg, reg.registerOptions)`.
72
- */
73
- readonly registerOptions?: WebMcpRegisterToolOptions;
74
- }
75
- /**
76
- * `ToolAnnotations` — optional behavior hints a host UI or agent may use to decide how to treat a
77
- * tool without calling it. Both default to `false` in the spec; this projection only ever sets
78
- * `readOnlyHint` by default (from {@link CapabilityDef.risk}) and leaves `untrustedContentHint`
79
- * unset unless a caller supplies one, since nothing in {@link CapabilityDef} implies it.
80
- */
81
- export interface WebMcpToolAnnotations {
82
- /** True when the tool never mutates state. Defaults from `capability.risk === 'read'`. */
83
- readonly readOnlyHint?: boolean;
84
- /** True when the tool's return value may contain content from outside the page's trust boundary. */
85
- readonly untrustedContentHint?: boolean;
86
- }
87
- /**
88
- * `ModelContextRegisterToolOptions` — the second positional argument to the real
89
- * `registerTool(tool, options)`, per the spec IDL:
90
- * `dictionary ModelContextRegisterToolOptions { AbortSignal signal; sequence<USVString> exposedTo; }`.
91
- */
92
- export interface WebMcpRegisterToolOptions {
93
- /**
94
- * Aborting this unregisters the tool and rejects the in-flight `registerTool()` promise with the
95
- * signal's abort reason — the spec's ONLY unregistration mechanism. There is no `unregisterTool()`
96
- * in the current draft; a host that wants to drop a tool later must have registered it with a
97
- * signal in the first place.
98
- */
99
- readonly signal?: AbortSignal;
100
- /** Origins (besides same-origin, always allowed) that may see and call this tool from other documents in the same tree. */
101
- readonly exposedTo?: readonly string[];
102
- }
103
- /** What a confirmation handler is asked to approve. */
104
- export interface WebMcpUserInteraction {
105
- readonly capability: CapabilityDef;
106
- readonly args: Record<string, unknown>;
107
- }
108
- /**
109
- * Asks the human to approve one call before it runs. Resolve `true` to proceed, `false` to refuse.
110
- *
111
- * **This is Jini's hook, not the browser's.** Earlier WebMCP drafts floated a
112
- * `requestUserInteraction()` on the page's model-context surface; the current draft
113
- * (https://webmachinelearning.github.io/webmcp/) does not define one, so there is nothing to
114
- * feature-detect and nothing standard to call. A host that wants a confirmed WebMCP tool supplies
115
- * this itself.
116
- *
117
- * Independently re-confirmed 2026-07-28: the reference polyfill `@mcp-b/webmcp-polyfill` (the
118
- * `MCP-B`/`WebMCP-org` community project, not the W3C CG spec) DOES pass a second
119
- * `client: { requestUserInteraction(callback) }` argument to `execute`, as one of its own
120
- * non-standard "MCPB extensions". That is further evidence the idea is real and wanted, and
121
- * further confirmation it is NOT part of the standardized `ToolExecuteCallback` — whose IDL is
122
- * `Promise<any> (object input)`, one argument. This module's `execute` wrapper below takes one
123
- * argument for exactly that reason; a second, ignored argument from a polyfill is harmless.
124
- */
125
- export type RequestUserInteraction = (interaction: WebMcpUserInteraction) => Promise<boolean>;
126
- export interface ToWebMcpToolOptions {
127
- readonly requestUserInteraction?: RequestUserInteraction;
128
- /**
129
- * `ModelContextTool.title`. Meaningful per-capability, so pass this through {@link toWebMcpTool}
130
- * (one capability) rather than {@link toWebMcpTools} (a whole manifest) — the latter shares one
131
- * `options` object across every capability in the batch, and a shared title would repeat
132
- * verbatim across dissimilar tools.
133
- */
134
- readonly title?: string;
135
- /**
136
- * Overrides or extends the default `annotations` (`{ readOnlyHint: capability.risk === 'read' }`).
137
- * Fields set here win over the default.
138
- */
139
- readonly annotations?: WebMcpToolAnnotations;
140
- /** See {@link WebMcpRegisterToolOptions.signal}. Safe to share across a whole {@link toWebMcpTools} batch — one `AbortController` per registration session, aborted once on teardown. */
141
- readonly signal?: AbortSignal;
142
- /** See {@link WebMcpRegisterToolOptions.exposedTo}. Safe to share across a whole {@link toWebMcpTools} batch when every capability in it gets the same scoping. */
143
- readonly exposedTo?: readonly string[];
144
- }
145
- /** Thrown in place of executing, when a call needed confirmation and did not get it. */
146
- export declare class WebMcpConfirmationRequiredError extends Error {
147
- readonly capabilityId: string;
148
- readonly reason: 'declined' | 'no-handler';
149
- constructor(capabilityId: string, reason: 'declined' | 'no-handler');
150
- }
151
- /** Whether `name` satisfies the spec's tool-name rule. Exported so a caller can pre-check a manifest without registering anything. */
152
- export declare function isValidWebMcpToolName(name: string): boolean;
153
- /**
154
- * Thrown synchronously by {@link toWebMcpTool} for a capability whose `id` cannot legally become a
155
- * WebMCP tool name. Distinct from {@link WebMcpConfirmationRequiredError}: this is a manifest
156
- * defect caught before any registration is attempted, not a runtime refusal of a call.
157
- */
158
- export declare class InvalidWebMcpToolNameError extends Error {
159
- readonly capabilityId: string;
160
- constructor(capabilityId: string);
161
- }
162
- /**
163
- * Projects one capability into a WebMCP registration.
164
- *
165
- * **The confirmation gate is fail-closed.** A capability with `requiresConfirmation` will not run
166
- * unless `options.requestUserInteraction` is supplied *and* resolves `true`. Omitting the handler
167
- * does not silently downgrade to "just run it" — it makes the tool permanently refuse, which is
168
- * the only safe reading of a manifest that asked for confirmation.
169
- *
170
- * This does not make WebMCP governed. It is a page-local gate over a path that still has no run,
171
- * no principal, no `ToolExecutor` and no audit trail (see this package's `frontend-session-registry`
172
- * note and §11 of the capability report). It closes the *accidental* case — a destructive
173
- * capability reaching the page with nothing in front of it — not the authorization gap.
174
- *
175
- * @param capability - The capability to expose.
176
- * @param execute - Runs the capability. Receives the raw argument object, already checked against
177
- * `capability.inputSchema` — a caller-supplied value that fails validation never reaches this.
178
- * @param options - Optional confirmation handler, title/annotations, and registration options
179
- * (`signal`/`exposedTo`); required in practice for any capability declaring `requiresConfirmation`.
180
- * @returns The registration object to hand to `registerTool`.
181
- * @throws {@link InvalidWebMcpToolNameError} synchronously, if `capability.id` cannot be a WebMCP
182
- * tool name.
183
- * @throws {@link WebMcpConfirmationRequiredError} from `execute`, when confirmation is required
184
- * and is either declined or unobtainable.
185
- */
186
- export declare function toWebMcpTool(capability: CapabilityDef, execute: (id: string, args: Record<string, unknown>) => Promise<unknown>, options?: ToWebMcpToolOptions): WebMcpToolRegistration;
187
- /**
188
- * Projects a whole manifest.
189
- *
190
- * `options` is shared across every capability — safe for `requestUserInteraction`, `signal`, and
191
- * `exposedTo`, which are naturally uniform for one registration session; do not pass `title`
192
- * through this one, since it would repeat verbatim across every tool in the manifest (see
193
- * {@link ToWebMcpToolOptions.title}).
194
- *
195
- * @param capabilities - Capabilities to expose, already filtered by whatever policy applies.
196
- * @param execute - Shared dispatcher, keyed by capability id.
197
- * @returns One registration per capability, in manifest order.
198
- * @throws {@link InvalidWebMcpToolNameError} synchronously, for the first capability whose `id`
199
- * cannot be a WebMCP tool name.
200
- */
201
- export declare function toWebMcpTools(capabilities: readonly CapabilityDef[], execute: (id: string, args: Record<string, unknown>) => Promise<unknown>, options?: ToWebMcpToolOptions): readonly WebMcpToolRegistration[];
202
- //# sourceMappingURL=webmcp.d.ts.map
package/dist/webmcp.js DELETED
@@ -1,173 +0,0 @@
1
- /**
2
- * @module webmcp
3
- *
4
- * Projection: {@link CapabilityDef} → a WebMCP tool registration.
5
- *
6
- * WebMCP (`document.modelContext.registerTool`) is the browser API by which a *page* offers
7
- * tools to an agent running inside the browser. It is a W3C Community Group draft, not a
8
- * standards-track spec, and it moves: the API relocated from `navigator.modelContext` to
9
- * `document.modelContext` on 2026-07-21, Chrome 150 deprecated the `navigator` location while
10
- * still serving it during the origin trial (Chrome 149–156), Edge ships it behind a flag, and
11
- * Firefox and Safari have made no commitment. Feature detection must therefore check `document`
12
- * first and fall back to `navigator`.
13
- *
14
- * That detection is deliberately NOT here: it touches browser globals, and this package holds
15
- * none. Framework bindings own host access; this file owns only the shape translation, so when
16
- * the registration shape changes again there is exactly one place to change it.
17
- *
18
- * Re-verified 2026-07-28 against the primary spec source
19
- * (https://webmachinelearning.github.io/webmcp/, `index.bs`). Four real gaps closed this pass,
20
- * all additive — none change the confirmation gate below, which is Jini's own addition and has
21
- * no spec counterpart:
22
- *
23
- * 1. **`signal`/`exposedTo`** — `ModelContextRegisterToolOptions`, the *second* positional
24
- * argument to `registerTool(tool, options)`. `signal` is the spec's ONLY unregistration
25
- * mechanism (there is no `unregisterTool()`); aborting it removes the tool and fires
26
- * `toolchange`. `exposedTo` scopes which cross-origin documents in the same tree may see the
27
- * tool. Neither belongs on the `ModelContextTool` dict itself, so they are not fields of
28
- * {@link WebMcpToolRegistration} — they ride along on its optional `registerOptions`, computed
29
- * from {@link ToWebMcpToolOptions}, so a caller has exactly one object to destructure:
30
- * `modelContext.registerTool(reg, reg.registerOptions)`.
31
- * 2. **`title`/`annotations`** — real `ModelContextTool` dict fields (`USVString title`,
32
- * `ToolAnnotations annotations`), now on {@link WebMcpToolRegistration}. `annotations.readOnlyHint`
33
- * defaults from {@link CapabilityDef.risk} (`'read'` → `true`) since Jini's manifests already
34
- * carry that judgment; a caller may override or add `untrustedContentHint` via `options.annotations`.
35
- * 3. **Tool name validation** — the spec's `registerTool` algorithm rejects (with an
36
- * `InvalidStateError` `DOMException`) a name that is empty, over 128 code points, or contains
37
- * anything outside ASCII alphanumeric plus `_`, `-`, `.`. `capability.id` becomes `name`
38
- * verbatim, so a malformed manifest entry previously surfaced as a cryptic browser-side
39
- * rejection days later; {@link toWebMcpTool} now checks it at projection time and names the
40
- * offending capability.
41
- * 4. **Schema-on-error** — WebMCP defines no input validation of its own (the spec's
42
- * `ToolExecuteCallback` is just `Promise<any> (object input)`), and this module's own doc used
43
- * to say so ("the caller is responsible for validating it... WebMCP does not"). That left a
44
- * wrong-schema call to fail deep inside whatever `execute` does, with no way for the caller to
45
- * self-correct in the same turn. `execute` now runs the manifest's own
46
- * {@link findCapabilityInputError} first and, on failure, throws the same
47
- * `"<id>: <reason>. Expected input: <schema>"` shape `page-executor.ts` already uses for
48
- * `page.*` — one discipline, not two.
49
- */
50
- import { findCapabilityInputError } from './capability.js';
51
- /** Thrown in place of executing, when a call needed confirmation and did not get it. */
52
- export class WebMcpConfirmationRequiredError extends Error {
53
- capabilityId;
54
- reason;
55
- constructor(capabilityId, reason) {
56
- super(reason === 'declined'
57
- ? `WebMCP: "${capabilityId}" was declined by the user`
58
- : `WebMCP: "${capabilityId}" requires confirmation, but no requestUserInteraction handler was supplied`);
59
- this.capabilityId = capabilityId;
60
- this.reason = reason;
61
- this.name = 'WebMcpConfirmationRequiredError';
62
- }
63
- }
64
- /**
65
- * The spec's tool-name rule, verbatim: "The tool definition's name's length must be between 1 and
66
- * 128, inclusive, and only consist of ASCII alphanumeric code points, U+005F LOW LINE (_), U+002D
67
- * HYPHEN-MINUS (-), and U+002E FULL STOP (.)." A name outside this is rejected by `registerTool`
68
- * with an `InvalidStateError` `DOMException` — this projection checks it earlier, at manifest time.
69
- */
70
- const WEBMCP_TOOL_NAME_PATTERN = /^[A-Za-z0-9_.-]{1,128}$/;
71
- /** Whether `name` satisfies the spec's tool-name rule. Exported so a caller can pre-check a manifest without registering anything. */
72
- export function isValidWebMcpToolName(name) {
73
- return WEBMCP_TOOL_NAME_PATTERN.test(name);
74
- }
75
- /**
76
- * Thrown synchronously by {@link toWebMcpTool} for a capability whose `id` cannot legally become a
77
- * WebMCP tool name. Distinct from {@link WebMcpConfirmationRequiredError}: this is a manifest
78
- * defect caught before any registration is attempted, not a runtime refusal of a call.
79
- */
80
- export class InvalidWebMcpToolNameError extends Error {
81
- capabilityId;
82
- constructor(capabilityId) {
83
- super(`WebMCP: capability id "${capabilityId}" is not a valid tool name — the spec requires 1-128 `
84
- + 'ASCII alphanumeric characters plus "_", "-", "." '
85
- + '(https://webmachinelearning.github.io/webmcp/#dom-modelcontext-registertool)');
86
- this.capabilityId = capabilityId;
87
- this.name = 'InvalidWebMcpToolNameError';
88
- }
89
- }
90
- /**
91
- * Projects one capability into a WebMCP registration.
92
- *
93
- * **The confirmation gate is fail-closed.** A capability with `requiresConfirmation` will not run
94
- * unless `options.requestUserInteraction` is supplied *and* resolves `true`. Omitting the handler
95
- * does not silently downgrade to "just run it" — it makes the tool permanently refuse, which is
96
- * the only safe reading of a manifest that asked for confirmation.
97
- *
98
- * This does not make WebMCP governed. It is a page-local gate over a path that still has no run,
99
- * no principal, no `ToolExecutor` and no audit trail (see this package's `frontend-session-registry`
100
- * note and §11 of the capability report). It closes the *accidental* case — a destructive
101
- * capability reaching the page with nothing in front of it — not the authorization gap.
102
- *
103
- * @param capability - The capability to expose.
104
- * @param execute - Runs the capability. Receives the raw argument object, already checked against
105
- * `capability.inputSchema` — a caller-supplied value that fails validation never reaches this.
106
- * @param options - Optional confirmation handler, title/annotations, and registration options
107
- * (`signal`/`exposedTo`); required in practice for any capability declaring `requiresConfirmation`.
108
- * @returns The registration object to hand to `registerTool`.
109
- * @throws {@link InvalidWebMcpToolNameError} synchronously, if `capability.id` cannot be a WebMCP
110
- * tool name.
111
- * @throws {@link WebMcpConfirmationRequiredError} from `execute`, when confirmation is required
112
- * and is either declined or unobtainable.
113
- */
114
- export function toWebMcpTool(capability, execute, options = {}) {
115
- if (!isValidWebMcpToolName(capability.id)) {
116
- throw new InvalidWebMcpToolNameError(capability.id);
117
- }
118
- const { title, annotations, signal, exposedTo } = options;
119
- const resolvedAnnotations = {
120
- readOnlyHint: capability.risk === 'read',
121
- ...annotations,
122
- };
123
- const registerOptions = signal !== undefined || exposedTo !== undefined
124
- ? { ...(signal !== undefined ? { signal } : {}), ...(exposedTo !== undefined ? { exposedTo } : {}) }
125
- : undefined;
126
- return {
127
- name: capability.id,
128
- ...(title !== undefined ? { title } : {}),
129
- description: capability.description,
130
- inputSchema: capability.inputSchema,
131
- execute: async (args) => {
132
- const input = args ?? {};
133
- // Schema-on-error, matching page-executor.ts's discipline for page.* — WebMCP defines no
134
- // input validation of its own, so a wrong-schema call would otherwise reach `execute` (or a
135
- // confirmation prompt for one) with bad arguments instead of a same-turn correctable error.
136
- const inputError = findCapabilityInputError(capability, input);
137
- if (inputError !== null) {
138
- throw new Error(`${capability.id}: ${inputError}. Expected input: ${JSON.stringify(capability.inputSchema)}`);
139
- }
140
- if (capability.requiresConfirmation === true) {
141
- const { requestUserInteraction } = options;
142
- if (!requestUserInteraction) {
143
- throw new WebMcpConfirmationRequiredError(capability.id, 'no-handler');
144
- }
145
- const approved = await requestUserInteraction({ capability, args: input });
146
- if (approved !== true) {
147
- throw new WebMcpConfirmationRequiredError(capability.id, 'declined');
148
- }
149
- }
150
- return execute(capability.id, input);
151
- },
152
- annotations: resolvedAnnotations,
153
- ...(registerOptions !== undefined ? { registerOptions } : {}),
154
- };
155
- }
156
- /**
157
- * Projects a whole manifest.
158
- *
159
- * `options` is shared across every capability — safe for `requestUserInteraction`, `signal`, and
160
- * `exposedTo`, which are naturally uniform for one registration session; do not pass `title`
161
- * through this one, since it would repeat verbatim across every tool in the manifest (see
162
- * {@link ToWebMcpToolOptions.title}).
163
- *
164
- * @param capabilities - Capabilities to expose, already filtered by whatever policy applies.
165
- * @param execute - Shared dispatcher, keyed by capability id.
166
- * @returns One registration per capability, in manifest order.
167
- * @throws {@link InvalidWebMcpToolNameError} synchronously, for the first capability whose `id`
168
- * cannot be a WebMCP tool name.
169
- */
170
- export function toWebMcpTools(capabilities, execute, options = {}) {
171
- return capabilities.map((capability) => toWebMcpTool(capability, execute, options));
172
- }
173
- //# sourceMappingURL=webmcp.js.map