auto-webmcp 0.3.17 → 0.3.18
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/dist/auto-webmcp.cjs.js +118 -4
- package/dist/auto-webmcp.cjs.js.map +2 -2
- package/dist/auto-webmcp.esm.js +118 -4
- package/dist/auto-webmcp.esm.js.map +2 -2
- package/dist/auto-webmcp.iife.js +1 -1
- package/dist/auto-webmcp.iife.js.map +3 -3
- package/dist/config.d.ts +7 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/interceptor.d.ts +10 -0
- package/dist/interceptor.d.ts.map +1 -1
- package/dist/registry.d.ts +1 -0
- package/dist/registry.d.ts.map +1 -1
- package/package.json +1 -1
package/dist/auto-webmcp.cjs.js
CHANGED
|
@@ -40,6 +40,7 @@ function resolveConfig(userConfig) {
|
|
|
40
40
|
timeoutMs: Math.max(100, userConfig?.execution?.timeoutMs ?? 15e3)
|
|
41
41
|
},
|
|
42
42
|
overrides: userConfig?.overrides ?? {},
|
|
43
|
+
preserveExisting: userConfig?.preserveExisting ?? false,
|
|
43
44
|
debug: userConfig?.debug ?? false
|
|
44
45
|
};
|
|
45
46
|
}
|
|
@@ -999,6 +1000,53 @@ function buildSchemaFromInputs(inputs) {
|
|
|
999
1000
|
}
|
|
1000
1001
|
|
|
1001
1002
|
// src/registry.ts
|
|
1003
|
+
var EXECUTE_OUTPUT_SCHEMA = {
|
|
1004
|
+
type: "object",
|
|
1005
|
+
properties: {
|
|
1006
|
+
status: {
|
|
1007
|
+
type: "string",
|
|
1008
|
+
enum: ["success", "partial", "error", "awaiting_user_action", "timed_out", "blocked_invalid"],
|
|
1009
|
+
description: "Outcome of the form execution."
|
|
1010
|
+
},
|
|
1011
|
+
filled_fields: {
|
|
1012
|
+
type: "object",
|
|
1013
|
+
description: "Field name to submitted value map."
|
|
1014
|
+
},
|
|
1015
|
+
skipped_fields: {
|
|
1016
|
+
type: "array",
|
|
1017
|
+
items: { type: "string" },
|
|
1018
|
+
description: "Fields the agent provided but that could not be filled."
|
|
1019
|
+
},
|
|
1020
|
+
missing_required: {
|
|
1021
|
+
type: "array",
|
|
1022
|
+
items: { type: "string" },
|
|
1023
|
+
description: "Required fields not supplied by the agent."
|
|
1024
|
+
},
|
|
1025
|
+
validation_errors: {
|
|
1026
|
+
type: "array",
|
|
1027
|
+
items: {
|
|
1028
|
+
type: "object",
|
|
1029
|
+
properties: {
|
|
1030
|
+
field: { type: "string" },
|
|
1031
|
+
constraint: { type: "string", description: "HTML ValidityState key that failed." },
|
|
1032
|
+
message: { type: "string" }
|
|
1033
|
+
},
|
|
1034
|
+
required: ["field", "constraint", "message"]
|
|
1035
|
+
},
|
|
1036
|
+
description: "Per-field HTML5 validation failures (present when status is blocked_invalid)."
|
|
1037
|
+
},
|
|
1038
|
+
existing_values: {
|
|
1039
|
+
type: "object",
|
|
1040
|
+
description: "Field values present in the form before the agent filled it."
|
|
1041
|
+
},
|
|
1042
|
+
warnings: {
|
|
1043
|
+
type: "array",
|
|
1044
|
+
items: { type: "object" },
|
|
1045
|
+
description: "Non-fatal fill warnings (alias_resolved, clamped, not_filled, etc.)."
|
|
1046
|
+
}
|
|
1047
|
+
},
|
|
1048
|
+
required: ["status", "filled_fields", "skipped_fields", "missing_required", "warnings"]
|
|
1049
|
+
};
|
|
1002
1050
|
var registeredTools = /* @__PURE__ */ new Map();
|
|
1003
1051
|
var registrationControllers = /* @__PURE__ */ new Map();
|
|
1004
1052
|
function isWebMCPSupported() {
|
|
@@ -1015,6 +1063,7 @@ async function registerFormTool(form, metadata, execute) {
|
|
|
1015
1063
|
name: metadata.name,
|
|
1016
1064
|
description: metadata.description,
|
|
1017
1065
|
inputSchema: metadata.inputSchema,
|
|
1066
|
+
outputSchema: EXECUTE_OUTPUT_SCHEMA,
|
|
1018
1067
|
execute
|
|
1019
1068
|
};
|
|
1020
1069
|
if (metadata.annotations && Object.keys(metadata.annotations).length > 0) {
|
|
@@ -1068,6 +1117,7 @@ var formFieldElements = /* @__PURE__ */ new WeakMap();
|
|
|
1068
1117
|
var pendingWarnings = /* @__PURE__ */ new WeakMap();
|
|
1069
1118
|
var pendingFillWarnings = /* @__PURE__ */ new WeakMap();
|
|
1070
1119
|
var lastFilledSnapshot = /* @__PURE__ */ new WeakMap();
|
|
1120
|
+
var preFillValues = /* @__PURE__ */ new WeakMap();
|
|
1071
1121
|
var _inputValueSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "value")?.set;
|
|
1072
1122
|
var _textareaValueSetter = Object.getOwnPropertyDescriptor(HTMLTextAreaElement.prototype, "value")?.set;
|
|
1073
1123
|
var _checkedSetter = Object.getOwnPropertyDescriptor(HTMLInputElement.prototype, "checked")?.set;
|
|
@@ -1159,6 +1209,36 @@ function collectInvalidFieldWarnings(form) {
|
|
|
1159
1209
|
}
|
|
1160
1210
|
return warnings;
|
|
1161
1211
|
}
|
|
1212
|
+
function captureCurrentValues(form) {
|
|
1213
|
+
const result = {};
|
|
1214
|
+
try {
|
|
1215
|
+
const data = new FormData(form);
|
|
1216
|
+
for (const [key, val] of data.entries()) {
|
|
1217
|
+
if (result[key] !== void 0) {
|
|
1218
|
+
const existing = result[key];
|
|
1219
|
+
result[key] = Array.isArray(existing) ? [...existing, val] : [existing, val];
|
|
1220
|
+
} else {
|
|
1221
|
+
result[key] = val;
|
|
1222
|
+
}
|
|
1223
|
+
}
|
|
1224
|
+
} catch {
|
|
1225
|
+
}
|
|
1226
|
+
return result;
|
|
1227
|
+
}
|
|
1228
|
+
function collectValidationErrors(form) {
|
|
1229
|
+
const errors = [];
|
|
1230
|
+
for (const control of Array.from(form.elements)) {
|
|
1231
|
+
if (!(control instanceof HTMLInputElement) && !(control instanceof HTMLTextAreaElement) && !(control instanceof HTMLSelectElement))
|
|
1232
|
+
continue;
|
|
1233
|
+
if (!control.willValidate || control.checkValidity())
|
|
1234
|
+
continue;
|
|
1235
|
+
const field = control.name || control.id || control.getAttribute("aria-label") || "unknown_field";
|
|
1236
|
+
const v = control.validity;
|
|
1237
|
+
const constraint = v.valueMissing ? "valueMissing" : v.typeMismatch ? "typeMismatch" : v.patternMismatch ? "patternMismatch" : v.tooLong ? "tooLong" : v.tooShort ? "tooShort" : v.rangeUnderflow ? "rangeUnderflow" : v.rangeOverflow ? "rangeOverflow" : v.stepMismatch ? "stepMismatch" : v.customError ? "customError" : "badInput";
|
|
1238
|
+
errors.push({ field, constraint, message: control.validationMessage || `field "${field}" failed validation` });
|
|
1239
|
+
}
|
|
1240
|
+
return errors;
|
|
1241
|
+
}
|
|
1162
1242
|
function buildExecuteHandler(form, config, toolName, metadata) {
|
|
1163
1243
|
if (metadata?.fieldElements) {
|
|
1164
1244
|
formFieldElements.set(form, metadata.fieldElements);
|
|
@@ -1180,6 +1260,8 @@ function buildExecuteHandler(form, config, toolName, metadata) {
|
|
|
1180
1260
|
}
|
|
1181
1261
|
pendingFillWarnings.set(form, []);
|
|
1182
1262
|
pendingWarnings.delete(form);
|
|
1263
|
+
const existingSnapshot = captureCurrentValues(form);
|
|
1264
|
+
preFillValues.set(form, existingSnapshot);
|
|
1183
1265
|
const { resolved: resolvedParams, warnings: aliasWarnings } = resolveParamsForSchema(
|
|
1184
1266
|
form,
|
|
1185
1267
|
params,
|
|
@@ -1189,7 +1271,28 @@ function buildExecuteHandler(form, config, toolName, metadata) {
|
|
|
1189
1271
|
if (aliasWarnings.length > 0) {
|
|
1190
1272
|
pendingFillWarnings.set(form, [...pendingFillWarnings.get(form) ?? [], ...aliasWarnings]);
|
|
1191
1273
|
}
|
|
1192
|
-
|
|
1274
|
+
let paramsToFill = resolvedParams;
|
|
1275
|
+
if (config.preserveExisting) {
|
|
1276
|
+
const preserved = [];
|
|
1277
|
+
paramsToFill = Object.fromEntries(
|
|
1278
|
+
Object.entries(resolvedParams).filter(([key]) => {
|
|
1279
|
+
const current = existingSnapshot[key];
|
|
1280
|
+
const hasValue = current !== void 0 && current !== "" && current !== null;
|
|
1281
|
+
if (hasValue) {
|
|
1282
|
+
preserved.push({
|
|
1283
|
+
field: key,
|
|
1284
|
+
type: "not_filled",
|
|
1285
|
+
message: `field "${key}" already has a value and preserveExisting is enabled`
|
|
1286
|
+
});
|
|
1287
|
+
}
|
|
1288
|
+
return !hasValue;
|
|
1289
|
+
})
|
|
1290
|
+
);
|
|
1291
|
+
if (preserved.length > 0) {
|
|
1292
|
+
pendingFillWarnings.set(form, [...pendingFillWarnings.get(form) ?? [], ...preserved]);
|
|
1293
|
+
}
|
|
1294
|
+
}
|
|
1295
|
+
fillFormFields(form, paramsToFill);
|
|
1193
1296
|
const missingNow = getMissingRequired(metadata, resolvedParams);
|
|
1194
1297
|
if (missingNow.length > 0)
|
|
1195
1298
|
pendingWarnings.set(form, missingNow);
|
|
@@ -1207,16 +1310,19 @@ function buildExecuteHandler(form, config, toolName, metadata) {
|
|
|
1207
1310
|
type: "timeout",
|
|
1208
1311
|
message: timedOutState === "timed_out" ? `tool execution timed out after ${timeoutMs}ms` : `waiting for user submit (timed out after ${timeoutMs}ms)`
|
|
1209
1312
|
};
|
|
1313
|
+
const _existingValsTimeout = preFillValues.get(form);
|
|
1210
1314
|
const structured = {
|
|
1211
1315
|
status: timedOutState,
|
|
1212
1316
|
filled_fields: serializeFormData(form, lastParams.get(form), formFieldElements.get(form)),
|
|
1213
1317
|
skipped_fields: [],
|
|
1214
1318
|
missing_required: pendingWarnings.get(form) ?? [],
|
|
1215
|
-
warnings: [...pendingFillWarnings.get(form) ?? [], warn]
|
|
1319
|
+
warnings: [...pendingFillWarnings.get(form) ?? [], warn],
|
|
1320
|
+
..._existingValsTimeout !== void 0 && { existing_values: _existingValsTimeout }
|
|
1216
1321
|
};
|
|
1217
1322
|
pendingWarnings.delete(form);
|
|
1218
1323
|
pendingFillWarnings.delete(form);
|
|
1219
1324
|
lastFilledSnapshot.delete(form);
|
|
1325
|
+
preFillValues.delete(form);
|
|
1220
1326
|
resolve({
|
|
1221
1327
|
content: [
|
|
1222
1328
|
{ type: "text", text: warn.message },
|
|
@@ -1267,17 +1373,21 @@ function buildExecuteHandler(form, config, toolName, metadata) {
|
|
|
1267
1373
|
];
|
|
1268
1374
|
pendingFillWarnings.delete(submitForm);
|
|
1269
1375
|
pendingFillWarnings.delete(form);
|
|
1376
|
+
const _existingValsBlocked = preFillValues.get(form);
|
|
1270
1377
|
const structured = {
|
|
1271
1378
|
status: "blocked_invalid",
|
|
1272
1379
|
filled_fields: serializeFormData(submitForm, lastParams.get(submitForm) ?? lastParams.get(form), formFieldElements.get(submitForm) ?? formFieldElements.get(form)),
|
|
1273
1380
|
skipped_fields: [],
|
|
1274
1381
|
missing_required: pendingWarnings.get(submitForm) ?? pendingWarnings.get(form) ?? [],
|
|
1275
|
-
warnings
|
|
1382
|
+
warnings,
|
|
1383
|
+
validation_errors: collectValidationErrors(submitForm),
|
|
1384
|
+
..._existingValsBlocked !== void 0 && { existing_values: _existingValsBlocked }
|
|
1276
1385
|
};
|
|
1277
1386
|
pendingWarnings.delete(submitForm);
|
|
1278
1387
|
pendingWarnings.delete(form);
|
|
1279
1388
|
lastFilledSnapshot.delete(submitForm);
|
|
1280
1389
|
lastFilledSnapshot.delete(form);
|
|
1390
|
+
preFillValues.delete(form);
|
|
1281
1391
|
resolve({
|
|
1282
1392
|
content: [
|
|
1283
1393
|
{ type: "text", text: "Form submission blocked by native validation." },
|
|
@@ -1309,7 +1419,9 @@ function attachSubmitInterceptor(form, toolName) {
|
|
|
1309
1419
|
clearTimeout(pending.timeoutId);
|
|
1310
1420
|
pendingExecutions.delete(form);
|
|
1311
1421
|
const formData = serializeFormData(form, lastParams.get(form), formFieldElements.get(form));
|
|
1422
|
+
const existingVals = preFillValues.get(form);
|
|
1312
1423
|
lastFilledSnapshot.delete(form);
|
|
1424
|
+
preFillValues.delete(form);
|
|
1313
1425
|
const missingRequired = pendingWarnings.get(form) ?? [];
|
|
1314
1426
|
pendingWarnings.delete(form);
|
|
1315
1427
|
const fillWarnings = pendingFillWarnings.get(form) ?? [];
|
|
@@ -1327,7 +1439,8 @@ function attachSubmitInterceptor(form, toolName) {
|
|
|
1327
1439
|
message: `required field "${f}" was not provided`
|
|
1328
1440
|
})),
|
|
1329
1441
|
...fillWarnings
|
|
1330
|
-
]
|
|
1442
|
+
],
|
|
1443
|
+
...existingVals !== void 0 && { existing_values: existingVals }
|
|
1331
1444
|
};
|
|
1332
1445
|
const allWarnMessages = [
|
|
1333
1446
|
...missingRequired.length ? [`required fields were not filled: ${missingRequired.join(", ")}`] : [],
|
|
@@ -1349,6 +1462,7 @@ function attachSubmitInterceptor(form, toolName) {
|
|
|
1349
1462
|
});
|
|
1350
1463
|
form.addEventListener("reset", () => {
|
|
1351
1464
|
lastFilledSnapshot.delete(form);
|
|
1465
|
+
preFillValues.delete(form);
|
|
1352
1466
|
window.dispatchEvent(new CustomEvent("toolcancel", { detail: { toolName } }));
|
|
1353
1467
|
});
|
|
1354
1468
|
}
|