@xpert-ai/chatkit-types 0.19.1 → 0.20.0

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/index.cjs CHANGED
@@ -243,6 +243,195 @@ function isHITLReviewDisplay(value) {
243
243
  }
244
244
  });
245
245
  }
246
+ const USER_INPUT_SUPPORTED_MODES = [
247
+ "blocking"
248
+ ];
249
+ const USER_INPUT_FORM_SCHEMA = {
250
+ type: "object",
251
+ additionalProperties: false,
252
+ required: ["schemaVersion", "mode", "purpose", "title", "fields"],
253
+ properties: {
254
+ schemaVersion: { type: "integer", const: 1 },
255
+ mode: { type: "string", enum: ["blocking"] },
256
+ purpose: { type: "string", const: "clarification" },
257
+ title: { type: "string", minLength: 1, maxLength: 160 },
258
+ description: { type: "string", maxLength: 2e3 },
259
+ fields: {
260
+ type: "array",
261
+ minItems: 1,
262
+ maxItems: 12,
263
+ items: {
264
+ type: "object",
265
+ additionalProperties: false,
266
+ required: ["id", "type", "label"],
267
+ properties: {
268
+ id: { type: "string", pattern: "^[a-zA-Z][a-zA-Z0-9_]{0,63}$" },
269
+ type: {
270
+ type: "string",
271
+ enum: [
272
+ "text",
273
+ "textarea",
274
+ "number",
275
+ "select",
276
+ "multiselect",
277
+ "boolean",
278
+ "date",
279
+ "date_range"
280
+ ]
281
+ },
282
+ label: { type: "string", minLength: 1, maxLength: 160 },
283
+ description: { type: "string", maxLength: 2e3 },
284
+ required: { type: "boolean" },
285
+ options: {
286
+ type: "array",
287
+ minItems: 1,
288
+ maxItems: 100,
289
+ items: {
290
+ type: "object",
291
+ additionalProperties: false,
292
+ required: ["value", "label"],
293
+ properties: {
294
+ value: { type: "string", minLength: 1, maxLength: 160 },
295
+ label: { type: "string", minLength: 1, maxLength: 160 }
296
+ }
297
+ }
298
+ },
299
+ min: { type: "number" },
300
+ max: { type: "number" },
301
+ minLength: { type: "integer", minimum: 0, maximum: 1e5 },
302
+ maxLength: { type: "integer", minimum: 0, maximum: 1e5 },
303
+ minItems: { type: "integer", minimum: 0, maximum: 100 },
304
+ maxItems: { type: "integer", minimum: 0, maximum: 100 }
305
+ }
306
+ }
307
+ }
308
+ }
309
+ };
310
+ function boundedText(value, max) {
311
+ return typeof value === "string" && value.trim().length > 0 && value.length <= max;
312
+ }
313
+ function isOption(value) {
314
+ return typeof value === "object" && value !== null && "value" in value && boundedText(value.value, 160) && "label" in value && boundedText(value.label, 160) && Object.keys(value).every((key) => key === "value" || key === "label");
315
+ }
316
+ function isField(value) {
317
+ if (!value || typeof value !== "object" || !("id" in value) || typeof value.id !== "string" || !/^[a-zA-Z][a-zA-Z0-9_]{0,63}$/.test(value.id) || ["constructor", "prototype", "__proto__"].includes(value.id) || !("type" in value) || typeof value.type !== "string" || ![
318
+ "text",
319
+ "textarea",
320
+ "number",
321
+ "select",
322
+ "multiselect",
323
+ "boolean",
324
+ "date",
325
+ "date_range"
326
+ ].includes(value.type) || !("label" in value) || !boundedText(value.label, 160))
327
+ return false;
328
+ if (Object.keys(value).some(
329
+ (key) => !Object.hasOwn(
330
+ USER_INPUT_FORM_SCHEMA.properties.fields.items.properties,
331
+ key
332
+ )
333
+ ))
334
+ return false;
335
+ if ("description" in value && (typeof value.description !== "string" || value.description.length > 2e3))
336
+ return false;
337
+ if ("required" in value && typeof value.required !== "boolean") return false;
338
+ if ("options" in value && (!Array.isArray(value.options) || value.options.length < 1 || value.options.length > 100 || !value.options.every(isOption) || new Set(value.options.map((option) => option.value)).size !== value.options.length))
339
+ return false;
340
+ if ((value.type === "select" || value.type === "multiselect") !== "options" in value)
341
+ return false;
342
+ for (const [key, limit] of [
343
+ ["minLength", 1e5],
344
+ ["maxLength", 1e5],
345
+ ["minItems", 100],
346
+ ["maxItems", 100]
347
+ ]) {
348
+ if (key in value) {
349
+ const bound = Reflect.get(value, key);
350
+ if (typeof bound !== "number" || !Number.isInteger(bound) || bound < 0 || bound > limit)
351
+ return false;
352
+ if (key === "minItems" || key === "maxItems" ? value.type !== "multiselect" : !["text", "textarea"].includes(value.type))
353
+ return false;
354
+ }
355
+ }
356
+ for (const key of ["min", "max"]) {
357
+ if (key in value && (value.type !== "number" || typeof Reflect.get(value, key) !== "number" || !Number.isFinite(Reflect.get(value, key))))
358
+ return false;
359
+ }
360
+ for (const [min, max] of [
361
+ ["min", "max"],
362
+ ["minLength", "maxLength"],
363
+ ["minItems", "maxItems"]
364
+ ]) {
365
+ if (min in value && max in value && Reflect.get(value, min) > Reflect.get(value, max))
366
+ return false;
367
+ }
368
+ return true;
369
+ }
370
+ function isRequestUserInputForm(value) {
371
+ return !!value && typeof value === "object" && "schemaVersion" in value && value.schemaVersion === 1 && "mode" in value && (value.mode === "blocking" || value.mode === "non_blocking") && "purpose" in value && value.purpose === "clarification" && "title" in value && boundedText(value.title, 160) && (!("description" in value) || typeof value.description === "string" && value.description.length <= 2e3) && "fields" in value && Array.isArray(value.fields) && value.fields.length > 0 && value.fields.length <= 12 && value.fields.every(isField) && new Set(value.fields.map((field) => field.id)).size === value.fields.length && Object.keys(value).every(
372
+ (key) => Object.hasOwn(USER_INPUT_FORM_SCHEMA.properties, key)
373
+ );
374
+ }
375
+ function isInputDate(value) {
376
+ if (typeof value !== "string" || !/^\d{4}-\d{2}-\d{2}$/.test(value))
377
+ return false;
378
+ const date = /* @__PURE__ */ new Date(`${value}T00:00:00.000Z`);
379
+ return Number.isFinite(date.getTime()) && date.toISOString().slice(0, 10) === value;
380
+ }
381
+ function validateField(field, value) {
382
+ var _a;
383
+ if (value === void 0 || value === "")
384
+ return field.required ? "required" : null;
385
+ if (Array.isArray(value) && value.length === 0 && field.required)
386
+ return "required";
387
+ switch (field.type) {
388
+ case "text":
389
+ case "textarea":
390
+ if (typeof value !== "string") return "type";
391
+ if (field.required && !value.trim()) return "required";
392
+ return value.length < (field.minLength ?? 0) || value.length > (field.maxLength ?? 1e5) ? "length" : null;
393
+ case "number":
394
+ if (typeof value !== "number" || !Number.isFinite(value)) return "type";
395
+ return value < (field.min ?? -Infinity) || value > (field.max ?? Infinity) ? "range" : null;
396
+ case "boolean":
397
+ return typeof value === "boolean" ? null : "type";
398
+ case "select":
399
+ return typeof value === "string" && ((_a = field.options) == null ? void 0 : _a.some((option) => option.value === value)) ? null : "choice";
400
+ case "multiselect":
401
+ if (!Array.isArray(value) || value.some(
402
+ (item) => {
403
+ var _a2;
404
+ return typeof item !== "string" || !((_a2 = field.options) == null ? void 0 : _a2.some((option) => option.value === item));
405
+ }
406
+ ) || new Set(value).size !== value.length)
407
+ return "choice";
408
+ return value.length < (field.minItems ?? 0) || value.length > (field.maxItems ?? 100) ? "length" : null;
409
+ case "date":
410
+ return isInputDate(value) ? null : "date";
411
+ case "date_range":
412
+ if (!value || typeof value !== "object" || !("start" in value) || !("end" in value) || !isInputDate(value.start) || !isInputDate(value.end) || Object.keys(value).some((key) => key !== "start" && key !== "end"))
413
+ return "date";
414
+ return value.start <= value.end ? null : "range";
415
+ }
416
+ }
417
+ function validateUserInputValues(form, input) {
418
+ if (!input || typeof input !== "object" || Array.isArray(input))
419
+ return { valid: false, errors: { _form: "type" } };
420
+ const errors = {};
421
+ const values = {};
422
+ for (const key of Object.keys(input)) {
423
+ if (!form.fields.some((field) => field.id === key))
424
+ return { valid: false, errors: { _form: "unknown" } };
425
+ }
426
+ for (const field of form.fields) {
427
+ const value = Object.hasOwn(input, field.id) ? Reflect.get(input, field.id) : void 0;
428
+ const error = validateField(field, value);
429
+ if (error) errors[field.id] = error;
430
+ else if (value !== void 0 && value !== "")
431
+ values[field.id] = value;
432
+ }
433
+ return Object.keys(errors).length ? { valid: false, errors } : { valid: true, values };
434
+ }
246
435
  const REQUEST_USER_INPUT_TOOL_NAME = "request_user_input";
247
436
  const REQUEST_USER_INPUT_RESULT_TYPE = "request_user_input_result";
248
437
  const REQUEST_USER_INPUT_RESULT_PURPOSE_PLAN_CLARIFICATION = "plan_clarification";
@@ -1254,6 +1443,8 @@ exports.REQUEST_USER_INPUT_RESULT_TYPE = REQUEST_USER_INPUT_RESULT_TYPE;
1254
1443
  exports.REQUEST_USER_INPUT_TOOL_NAME = REQUEST_USER_INPUT_TOOL_NAME;
1255
1444
  exports.TOOL_OUTPUT_PRESENTATION_TYPE = TOOL_OUTPUT_PRESENTATION_TYPE;
1256
1445
  exports.TOOL_OUTPUT_PRESENTATION_VERSION = TOOL_OUTPUT_PRESENTATION_VERSION;
1446
+ exports.USER_INPUT_FORM_SCHEMA = USER_INPUT_FORM_SCHEMA;
1447
+ exports.USER_INPUT_SUPPORTED_MODES = USER_INPUT_SUPPORTED_MODES;
1257
1448
  exports.chatSkillUsageKey = chatSkillUsageKey;
1258
1449
  exports.clampPetPosition = clampPetPosition;
1259
1450
  exports.countFileChangeLines = countFileChangeLines;
@@ -1280,10 +1471,12 @@ exports.isHITLInterruptPayload = isHITLInterruptPayload;
1280
1471
  exports.isHITLInterruptTask = isHITLInterruptTask;
1281
1472
  exports.isHITLRequest = isHITLRequest;
1282
1473
  exports.isHITLReviewDisplay = isHITLReviewDisplay;
1474
+ exports.isInputDate = isInputDate;
1283
1475
  exports.isInterruptRequest = isInterruptRequest;
1284
1476
  exports.isLangGraphInterrupt = isLangGraphInterrupt;
1285
1477
  exports.isLangGraphInterruptPayload = isLangGraphInterruptPayload;
1286
1478
  exports.isLangGraphInterruptTask = isLangGraphInterruptTask;
1479
+ exports.isRequestUserInputForm = isRequestUserInputForm;
1287
1480
  exports.isResourceCardContent = isResourceCardContent;
1288
1481
  exports.isToolCallInterrupt = isToolCallInterrupt;
1289
1482
  exports.isToolCallInterruptPayload = isToolCallInterruptPayload;
@@ -1313,4 +1506,5 @@ exports.resolvePetCharacter = resolvePetCharacter;
1313
1506
  exports.resourceCardId = resourceCardId;
1314
1507
  exports.upsertFileActivityContent = upsertFileActivityContent;
1315
1508
  exports.upsertResourceCardContent = upsertResourceCardContent;
1509
+ exports.validateUserInputValues = validateUserInputValues;
1316
1510
  //# sourceMappingURL=index.cjs.map