react-webmcp 0.2.0 → 0.2.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.
- package/README.md +135 -16
- package/dist/index.d.mts +292 -12
- package/dist/index.d.ts +292 -12
- package/dist/index.js +351 -17
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +331 -6
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
'use strict';
|
|
2
2
|
|
|
3
|
-
var
|
|
3
|
+
var React6 = require('react');
|
|
4
4
|
var jsxRuntime = require('react/jsx-runtime');
|
|
5
5
|
|
|
6
6
|
function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; }
|
|
7
7
|
|
|
8
|
-
var
|
|
8
|
+
var React6__default = /*#__PURE__*/_interopDefault(React6);
|
|
9
9
|
|
|
10
10
|
// src/hooks/useWebMCPTool.ts
|
|
11
11
|
|
|
@@ -37,11 +37,11 @@ function toolFingerprint(config) {
|
|
|
37
37
|
return `${config.name}::${config.description}::${JSON.stringify(config.inputSchema)}::${JSON.stringify(config.outputSchema ?? {})}::${JSON.stringify(config.annotations ?? {})}`;
|
|
38
38
|
}
|
|
39
39
|
function useWebMCPTool(config) {
|
|
40
|
-
const registeredNameRef =
|
|
41
|
-
const configRef =
|
|
40
|
+
const registeredNameRef = React6.useRef(null);
|
|
41
|
+
const configRef = React6.useRef(config);
|
|
42
42
|
configRef.current = config;
|
|
43
43
|
const fingerprint = toolFingerprint(config);
|
|
44
|
-
|
|
44
|
+
React6.useEffect(() => {
|
|
45
45
|
const mc = getModelContext();
|
|
46
46
|
if (!mc) {
|
|
47
47
|
warnIfUnavailable("useWebMCPTool");
|
|
@@ -93,10 +93,10 @@ function toolsFingerprint(tools) {
|
|
|
93
93
|
).join("|");
|
|
94
94
|
}
|
|
95
95
|
function useWebMCPContext(config) {
|
|
96
|
-
const toolsRef =
|
|
96
|
+
const toolsRef = React6.useRef(config.tools);
|
|
97
97
|
toolsRef.current = config.tools;
|
|
98
98
|
const fingerprint = toolsFingerprint(config.tools);
|
|
99
|
-
|
|
99
|
+
React6.useEffect(() => {
|
|
100
100
|
const mc = getModelContext();
|
|
101
101
|
if (!mc) {
|
|
102
102
|
warnIfUnavailable("useWebMCPContext");
|
|
@@ -137,7 +137,7 @@ function useWebMCPContext(config) {
|
|
|
137
137
|
}, [fingerprint]);
|
|
138
138
|
}
|
|
139
139
|
function useToolEvent(event, callback, toolNameFilter) {
|
|
140
|
-
|
|
140
|
+
React6.useEffect(() => {
|
|
141
141
|
const handler = (e) => {
|
|
142
142
|
const toolName = e.toolName ?? e.detail?.toolName;
|
|
143
143
|
if (!toolName) return;
|
|
@@ -160,8 +160,8 @@ function WebMCPForm({
|
|
|
160
160
|
children,
|
|
161
161
|
...rest
|
|
162
162
|
}) {
|
|
163
|
-
const formRef =
|
|
164
|
-
|
|
163
|
+
const formRef = React6.useRef(null);
|
|
164
|
+
React6.useEffect(() => {
|
|
165
165
|
const handleActivated = (e) => {
|
|
166
166
|
const name = e.toolName ?? e.detail?.toolName;
|
|
167
167
|
if (name === toolName && onToolActivated) {
|
|
@@ -181,7 +181,7 @@ function WebMCPForm({
|
|
|
181
181
|
window.removeEventListener("toolcancel", handleCancel);
|
|
182
182
|
};
|
|
183
183
|
}, [toolName, onToolActivated, onToolCancel]);
|
|
184
|
-
const handleSubmit =
|
|
184
|
+
const handleSubmit = React6.useCallback(
|
|
185
185
|
(e) => {
|
|
186
186
|
if (onSubmit) {
|
|
187
187
|
onSubmit(e.nativeEvent);
|
|
@@ -207,7 +207,7 @@ function WebMCPForm({
|
|
|
207
207
|
}
|
|
208
208
|
);
|
|
209
209
|
}
|
|
210
|
-
var WebMCPInput =
|
|
210
|
+
var WebMCPInput = React6__default.default.forwardRef(
|
|
211
211
|
({ toolParamTitle, toolParamDescription, ...rest }, ref) => {
|
|
212
212
|
const webmcpAttrs = {};
|
|
213
213
|
if (toolParamTitle) {
|
|
@@ -220,7 +220,7 @@ var WebMCPInput = React2__default.default.forwardRef(
|
|
|
220
220
|
}
|
|
221
221
|
);
|
|
222
222
|
WebMCPInput.displayName = "WebMCPInput";
|
|
223
|
-
var WebMCPSelect =
|
|
223
|
+
var WebMCPSelect = React6__default.default.forwardRef(({ toolParamTitle, toolParamDescription, children, ...rest }, ref) => {
|
|
224
224
|
const webmcpAttrs = {};
|
|
225
225
|
if (toolParamTitle) {
|
|
226
226
|
webmcpAttrs.toolparamtitle = toolParamTitle;
|
|
@@ -231,7 +231,7 @@ var WebMCPSelect = React2__default.default.forwardRef(({ toolParamTitle, toolPar
|
|
|
231
231
|
return /* @__PURE__ */ jsxRuntime.jsx("select", { ref, ...webmcpAttrs, ...rest, children });
|
|
232
232
|
});
|
|
233
233
|
WebMCPSelect.displayName = "WebMCPSelect";
|
|
234
|
-
var WebMCPTextarea =
|
|
234
|
+
var WebMCPTextarea = React6__default.default.forwardRef(({ toolParamTitle, toolParamDescription, ...rest }, ref) => {
|
|
235
235
|
const webmcpAttrs = {};
|
|
236
236
|
if (toolParamTitle) {
|
|
237
237
|
webmcpAttrs.toolparamtitle = toolParamTitle;
|
|
@@ -242,12 +242,12 @@ var WebMCPTextarea = React2__default.default.forwardRef(({ toolParamTitle, toolP
|
|
|
242
242
|
return /* @__PURE__ */ jsxRuntime.jsx("textarea", { ref, ...webmcpAttrs, ...rest });
|
|
243
243
|
});
|
|
244
244
|
WebMCPTextarea.displayName = "WebMCPTextarea";
|
|
245
|
-
var WebMCPReactContext =
|
|
245
|
+
var WebMCPReactContext = React6.createContext({
|
|
246
246
|
available: false,
|
|
247
247
|
testingAvailable: false
|
|
248
248
|
});
|
|
249
249
|
function WebMCPProvider({ children }) {
|
|
250
|
-
const value =
|
|
250
|
+
const value = React6.useMemo(
|
|
251
251
|
() => ({
|
|
252
252
|
available: isWebMCPAvailable(),
|
|
253
253
|
testingAvailable: isWebMCPTestingAvailable()
|
|
@@ -257,20 +257,354 @@ function WebMCPProvider({ children }) {
|
|
|
257
257
|
return /* @__PURE__ */ jsxRuntime.jsx(WebMCPReactContext.Provider, { value, children });
|
|
258
258
|
}
|
|
259
259
|
function useWebMCPStatus() {
|
|
260
|
-
return
|
|
260
|
+
return React6.useContext(WebMCPReactContext);
|
|
261
261
|
}
|
|
262
|
+
function extractOptions(children) {
|
|
263
|
+
const results = [];
|
|
264
|
+
React6__default.default.Children.toArray(children).forEach((child) => {
|
|
265
|
+
if (!React6__default.default.isValidElement(child)) return;
|
|
266
|
+
const props = child.props;
|
|
267
|
+
if (props.value !== void 0 && props.value !== null) {
|
|
268
|
+
const value = props.value;
|
|
269
|
+
let label;
|
|
270
|
+
if (typeof props.children === "string") {
|
|
271
|
+
label = props.children;
|
|
272
|
+
} else {
|
|
273
|
+
label = String(value);
|
|
274
|
+
}
|
|
275
|
+
results.push({ value, label });
|
|
276
|
+
}
|
|
277
|
+
if (props.children) {
|
|
278
|
+
results.push(...extractOptions(props.children));
|
|
279
|
+
}
|
|
280
|
+
});
|
|
281
|
+
return results;
|
|
282
|
+
}
|
|
283
|
+
function extractFields(children) {
|
|
284
|
+
const fields = [];
|
|
285
|
+
React6__default.default.Children.toArray(children).forEach((child) => {
|
|
286
|
+
if (!React6__default.default.isValidElement(child)) return;
|
|
287
|
+
const props = child.props;
|
|
288
|
+
const inputProps = props.inputProps;
|
|
289
|
+
const slotInput = props.slotProps?.input;
|
|
290
|
+
const name = props.name ?? inputProps?.name ?? slotInput?.name;
|
|
291
|
+
if (name) {
|
|
292
|
+
const field = { name };
|
|
293
|
+
if (props.type !== void 0) field.type = props.type;
|
|
294
|
+
if (props.required !== void 0) field.required = Boolean(props.required);
|
|
295
|
+
if (props.min !== void 0) field.min = Number(props.min);
|
|
296
|
+
if (props.max !== void 0) field.max = Number(props.max);
|
|
297
|
+
if (props.minLength !== void 0) field.minLength = Number(props.minLength);
|
|
298
|
+
if (props.maxLength !== void 0) field.maxLength = Number(props.maxLength);
|
|
299
|
+
if (props.pattern !== void 0) field.pattern = props.pattern;
|
|
300
|
+
if (props.children) {
|
|
301
|
+
const options = extractOptions(props.children);
|
|
302
|
+
if (options.length > 0) {
|
|
303
|
+
field.enumValues = options.map((o) => o.value);
|
|
304
|
+
field.oneOf = options;
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
fields.push(field);
|
|
308
|
+
} else if (props.children) {
|
|
309
|
+
fields.push(...extractFields(props.children));
|
|
310
|
+
}
|
|
311
|
+
});
|
|
312
|
+
return fields;
|
|
313
|
+
}
|
|
314
|
+
|
|
315
|
+
// src/adapters/buildSchema.ts
|
|
316
|
+
function mapHtmlTypeToSchemaType(htmlType) {
|
|
317
|
+
switch (htmlType) {
|
|
318
|
+
case "number":
|
|
319
|
+
case "range":
|
|
320
|
+
return "number";
|
|
321
|
+
case "checkbox":
|
|
322
|
+
return "boolean";
|
|
323
|
+
default:
|
|
324
|
+
return "string";
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
function buildInputSchema(fields) {
|
|
328
|
+
const properties = {};
|
|
329
|
+
const required = [];
|
|
330
|
+
const sortedFields = [...fields].sort((a, b) => a.name.localeCompare(b.name));
|
|
331
|
+
for (const field of sortedFields) {
|
|
332
|
+
const prop = {
|
|
333
|
+
type: mapHtmlTypeToSchemaType(field.type)
|
|
334
|
+
};
|
|
335
|
+
if (field.title) prop.title = field.title;
|
|
336
|
+
if (field.description) prop.description = field.description;
|
|
337
|
+
if (field.min !== void 0) prop.minimum = field.min;
|
|
338
|
+
if (field.max !== void 0) prop.maximum = field.max;
|
|
339
|
+
if (field.minLength !== void 0) prop.minLength = field.minLength;
|
|
340
|
+
if (field.maxLength !== void 0) prop.maxLength = field.maxLength;
|
|
341
|
+
if (field.pattern) prop.pattern = field.pattern;
|
|
342
|
+
if (field.enumValues && field.enumValues.length > 0) {
|
|
343
|
+
prop.enum = field.enumValues;
|
|
344
|
+
}
|
|
345
|
+
if (field.oneOf && field.oneOf.length > 0) {
|
|
346
|
+
prop.oneOf = field.oneOf.map((opt) => ({
|
|
347
|
+
const: opt.value,
|
|
348
|
+
title: opt.label
|
|
349
|
+
}));
|
|
350
|
+
}
|
|
351
|
+
properties[field.name] = prop;
|
|
352
|
+
if (field.required) {
|
|
353
|
+
required.push(field.name);
|
|
354
|
+
}
|
|
355
|
+
}
|
|
356
|
+
const schema = {
|
|
357
|
+
type: "object",
|
|
358
|
+
properties
|
|
359
|
+
};
|
|
360
|
+
if (required.length > 0) {
|
|
361
|
+
schema.required = required.sort();
|
|
362
|
+
}
|
|
363
|
+
return schema;
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
// src/adapters/validateSchema.ts
|
|
367
|
+
function validateSchema(fields, options) {
|
|
368
|
+
if (process.env.NODE_ENV === "production") return;
|
|
369
|
+
const strict = options?.strict ?? false;
|
|
370
|
+
const issues = [];
|
|
371
|
+
const seen = /* @__PURE__ */ new Set();
|
|
372
|
+
for (const field of fields) {
|
|
373
|
+
if (seen.has(field.name)) {
|
|
374
|
+
issues.push(`Duplicate field name "${field.name}".`);
|
|
375
|
+
}
|
|
376
|
+
seen.add(field.name);
|
|
377
|
+
const schemaType = mapHtmlTypeToSchemaType(field.type);
|
|
378
|
+
if (field.pattern !== void 0 && schemaType !== "string") {
|
|
379
|
+
issues.push(
|
|
380
|
+
`Field "${field.name}": pattern is only valid for string types, but type is "${schemaType}".`
|
|
381
|
+
);
|
|
382
|
+
}
|
|
383
|
+
if ((field.min !== void 0 || field.max !== void 0) && schemaType !== "number") {
|
|
384
|
+
issues.push(
|
|
385
|
+
`Field "${field.name}": min/max are only valid for number types, but type is "${schemaType}".`
|
|
386
|
+
);
|
|
387
|
+
}
|
|
388
|
+
if ((field.minLength !== void 0 || field.maxLength !== void 0) && schemaType !== "string") {
|
|
389
|
+
issues.push(
|
|
390
|
+
`Field "${field.name}": minLength/maxLength are only valid for string types, but type is "${schemaType}".`
|
|
391
|
+
);
|
|
392
|
+
}
|
|
393
|
+
if (field.enumValues && field.enumValues.length > 0) {
|
|
394
|
+
for (const val of field.enumValues) {
|
|
395
|
+
const valType = typeof val;
|
|
396
|
+
if (schemaType === "string" && valType !== "string") {
|
|
397
|
+
issues.push(
|
|
398
|
+
`Field "${field.name}": enum value ${JSON.stringify(val)} is not a string.`
|
|
399
|
+
);
|
|
400
|
+
}
|
|
401
|
+
if (schemaType === "number" && valType !== "number") {
|
|
402
|
+
issues.push(
|
|
403
|
+
`Field "${field.name}": enum value ${JSON.stringify(val)} is not a number.`
|
|
404
|
+
);
|
|
405
|
+
}
|
|
406
|
+
if (schemaType === "boolean" && valType !== "boolean") {
|
|
407
|
+
issues.push(
|
|
408
|
+
`Field "${field.name}": enum value ${JSON.stringify(val)} is not a boolean.`
|
|
409
|
+
);
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
for (const issue of issues) {
|
|
415
|
+
if (strict) {
|
|
416
|
+
throw new Error(`[react-webmcp] ${issue}`);
|
|
417
|
+
}
|
|
418
|
+
console.warn(`[react-webmcp] ${issue}`);
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
// src/adapters/useSchemaCollector.ts
|
|
423
|
+
var ToolContext = React6.createContext(null);
|
|
424
|
+
function fieldsFingerprint(fields) {
|
|
425
|
+
return fields.map(
|
|
426
|
+
(f) => `${f.name}::${f.type ?? ""}::${f.required ?? ""}::${f.title ?? ""}::${f.description ?? ""}::${JSON.stringify(f.enumValues ?? [])}::${JSON.stringify(f.oneOf ?? [])}::${f.min ?? ""}::${f.max ?? ""}::${f.minLength ?? ""}::${f.maxLength ?? ""}::${f.pattern ?? ""}`
|
|
427
|
+
).join("|");
|
|
428
|
+
}
|
|
429
|
+
function mergeField(base, override) {
|
|
430
|
+
const result = { ...base };
|
|
431
|
+
for (const key of Object.keys(override)) {
|
|
432
|
+
if (override[key] !== void 0) {
|
|
433
|
+
result[key] = override[key];
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
return result;
|
|
437
|
+
}
|
|
438
|
+
function useSchemaCollector({
|
|
439
|
+
children,
|
|
440
|
+
fields: fieldsProp,
|
|
441
|
+
strict
|
|
442
|
+
}) {
|
|
443
|
+
const contextFieldsRef = React6.useRef(/* @__PURE__ */ new Map());
|
|
444
|
+
const [version, setVersion] = React6.useState(0);
|
|
445
|
+
const registerField = React6.useCallback((field) => {
|
|
446
|
+
contextFieldsRef.current.set(field.name, field);
|
|
447
|
+
setVersion((v) => v + 1);
|
|
448
|
+
}, []);
|
|
449
|
+
const unregisterField = React6.useCallback((name) => {
|
|
450
|
+
contextFieldsRef.current.delete(name);
|
|
451
|
+
setVersion((v) => v + 1);
|
|
452
|
+
}, []);
|
|
453
|
+
const childrenFields = extractFields(children);
|
|
454
|
+
const childrenFP = fieldsFingerprint(childrenFields);
|
|
455
|
+
const merged = React6.useMemo(() => {
|
|
456
|
+
const fieldMap = /* @__PURE__ */ new Map();
|
|
457
|
+
for (const field of childrenFields) {
|
|
458
|
+
fieldMap.set(field.name, field);
|
|
459
|
+
}
|
|
460
|
+
if (fieldsProp) {
|
|
461
|
+
for (const [name, overrides] of Object.entries(fieldsProp)) {
|
|
462
|
+
const existing = fieldMap.get(name);
|
|
463
|
+
if (existing) {
|
|
464
|
+
fieldMap.set(name, mergeField(existing, overrides));
|
|
465
|
+
} else {
|
|
466
|
+
fieldMap.set(name, { name, ...overrides });
|
|
467
|
+
}
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
for (const [name, field] of contextFieldsRef.current) {
|
|
471
|
+
const existing = fieldMap.get(name);
|
|
472
|
+
if (existing) {
|
|
473
|
+
fieldMap.set(name, mergeField(existing, field));
|
|
474
|
+
} else {
|
|
475
|
+
fieldMap.set(name, field);
|
|
476
|
+
}
|
|
477
|
+
}
|
|
478
|
+
const result = Array.from(fieldMap.values());
|
|
479
|
+
if (process.env.NODE_ENV !== "production") {
|
|
480
|
+
validateSchema(result, { strict });
|
|
481
|
+
}
|
|
482
|
+
return result;
|
|
483
|
+
}, [childrenFP, fieldsProp, version, strict]);
|
|
484
|
+
const mergedFP = fieldsFingerprint(merged);
|
|
485
|
+
const schema = React6.useMemo(
|
|
486
|
+
() => buildInputSchema(merged),
|
|
487
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
488
|
+
[mergedFP]
|
|
489
|
+
);
|
|
490
|
+
return { schema, registerField, unregisterField };
|
|
491
|
+
}
|
|
492
|
+
function WebMCPTool({
|
|
493
|
+
name,
|
|
494
|
+
description,
|
|
495
|
+
onExecute,
|
|
496
|
+
fields: fieldsProp,
|
|
497
|
+
strict,
|
|
498
|
+
autoSubmit,
|
|
499
|
+
annotations,
|
|
500
|
+
onToolActivated,
|
|
501
|
+
onToolCancel,
|
|
502
|
+
children
|
|
503
|
+
}) {
|
|
504
|
+
const { schema, registerField, unregisterField } = useSchemaCollector({
|
|
505
|
+
children,
|
|
506
|
+
fields: fieldsProp,
|
|
507
|
+
strict
|
|
508
|
+
});
|
|
509
|
+
const executeRef = React6.useRef(onExecute);
|
|
510
|
+
executeRef.current = onExecute;
|
|
511
|
+
useWebMCPTool({
|
|
512
|
+
name,
|
|
513
|
+
description,
|
|
514
|
+
inputSchema: schema,
|
|
515
|
+
annotations,
|
|
516
|
+
execute: (input) => executeRef.current(input)
|
|
517
|
+
});
|
|
518
|
+
React6.useEffect(() => {
|
|
519
|
+
if (typeof window === "undefined") return;
|
|
520
|
+
if (!onToolActivated && !onToolCancel) return;
|
|
521
|
+
const handleActivated = (e) => {
|
|
522
|
+
const toolName = e.toolName ?? e.detail?.toolName;
|
|
523
|
+
if (toolName === name && onToolActivated) {
|
|
524
|
+
onToolActivated(toolName);
|
|
525
|
+
}
|
|
526
|
+
};
|
|
527
|
+
const handleCancel = (e) => {
|
|
528
|
+
const toolName = e.toolName ?? e.detail?.toolName;
|
|
529
|
+
if (toolName === name && onToolCancel) {
|
|
530
|
+
onToolCancel(toolName);
|
|
531
|
+
}
|
|
532
|
+
};
|
|
533
|
+
window.addEventListener("toolactivated", handleActivated);
|
|
534
|
+
window.addEventListener("toolcancel", handleCancel);
|
|
535
|
+
return () => {
|
|
536
|
+
window.removeEventListener("toolactivated", handleActivated);
|
|
537
|
+
window.removeEventListener("toolcancel", handleCancel);
|
|
538
|
+
};
|
|
539
|
+
}, [name, onToolActivated, onToolCancel]);
|
|
540
|
+
return /* @__PURE__ */ jsxRuntime.jsx(ToolContext.Provider, { value: { registerField, unregisterField }, children });
|
|
541
|
+
}
|
|
542
|
+
WebMCPTool.displayName = "WebMCP.Tool";
|
|
543
|
+
function fieldFingerprint(field) {
|
|
544
|
+
return `${field.name}::${field.type ?? ""}::${field.required ?? ""}::${field.title ?? ""}::${field.description ?? ""}::${JSON.stringify(field.enumValues ?? [])}::${JSON.stringify(field.oneOf ?? [])}::${field.min ?? ""}::${field.max ?? ""}::${field.minLength ?? ""}::${field.maxLength ?? ""}::${field.pattern ?? ""}`;
|
|
545
|
+
}
|
|
546
|
+
function useRegisterField(field) {
|
|
547
|
+
const ctx = React6.useContext(ToolContext);
|
|
548
|
+
const fp = fieldFingerprint(field);
|
|
549
|
+
React6.useEffect(() => {
|
|
550
|
+
if (!ctx) {
|
|
551
|
+
if (process.env.NODE_ENV !== "production") {
|
|
552
|
+
console.warn(
|
|
553
|
+
`[react-webmcp] useRegisterField: no WebMCP.Tool context found for field "${field.name}". Wrap this component in a <WebMCP.Tool> to register fields.`
|
|
554
|
+
);
|
|
555
|
+
}
|
|
556
|
+
return;
|
|
557
|
+
}
|
|
558
|
+
ctx.registerField(field);
|
|
559
|
+
return () => {
|
|
560
|
+
try {
|
|
561
|
+
ctx.unregisterField(field.name);
|
|
562
|
+
} catch {
|
|
563
|
+
}
|
|
564
|
+
};
|
|
565
|
+
}, [fp]);
|
|
566
|
+
}
|
|
567
|
+
function WebMCPField({
|
|
568
|
+
children,
|
|
569
|
+
name,
|
|
570
|
+
...rest
|
|
571
|
+
}) {
|
|
572
|
+
const field = { name, ...rest };
|
|
573
|
+
if (!field.enumValues && !field.oneOf) {
|
|
574
|
+
const options = extractOptions(children);
|
|
575
|
+
if (options.length > 0) {
|
|
576
|
+
field.enumValues = options.map((o) => o.value);
|
|
577
|
+
field.oneOf = options;
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
useRegisterField(field);
|
|
581
|
+
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children });
|
|
582
|
+
}
|
|
583
|
+
WebMCPField.displayName = "WebMCP.Field";
|
|
584
|
+
|
|
585
|
+
// src/adapters/index.ts
|
|
586
|
+
var WebMCP = { Tool: WebMCPTool, Field: WebMCPField };
|
|
262
587
|
|
|
588
|
+
exports.WebMCP = WebMCP;
|
|
589
|
+
exports.WebMCPField = WebMCPField;
|
|
263
590
|
exports.WebMCPForm = WebMCPForm;
|
|
264
591
|
exports.WebMCPInput = WebMCPInput;
|
|
265
592
|
exports.WebMCPProvider = WebMCPProvider;
|
|
266
593
|
exports.WebMCPSelect = WebMCPSelect;
|
|
267
594
|
exports.WebMCPTextarea = WebMCPTextarea;
|
|
595
|
+
exports.WebMCPTool = WebMCPTool;
|
|
596
|
+
exports.buildInputSchema = buildInputSchema;
|
|
597
|
+
exports.extractFields = extractFields;
|
|
598
|
+
exports.extractOptions = extractOptions;
|
|
268
599
|
exports.getModelContext = getModelContext;
|
|
269
600
|
exports.isWebMCPAvailable = isWebMCPAvailable;
|
|
270
601
|
exports.isWebMCPTestingAvailable = isWebMCPTestingAvailable;
|
|
602
|
+
exports.useRegisterField = useRegisterField;
|
|
603
|
+
exports.useSchemaCollector = useSchemaCollector;
|
|
271
604
|
exports.useToolEvent = useToolEvent;
|
|
272
605
|
exports.useWebMCPContext = useWebMCPContext;
|
|
273
606
|
exports.useWebMCPStatus = useWebMCPStatus;
|
|
274
607
|
exports.useWebMCPTool = useWebMCPTool;
|
|
608
|
+
exports.validateSchema = validateSchema;
|
|
275
609
|
//# sourceMappingURL=index.js.map
|
|
276
610
|
//# sourceMappingURL=index.js.map
|