UNPKG

@microsoft/teams-ai

Version:

SDK focused on building AI based applications for Microsoft Teams.

139 lines 6 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.JSONResponseValidator = void 0; const jsonschema_1 = require("jsonschema"); const Response_1 = require("./Response"); /** * Parses any JSON returned by the model and optionally verifies it against a JSON schema. * @template TValue Optional. Type of the validation value returned. Defaults to `Record<string, any>`. */ class JSONResponseValidator { /** * Creates a new `JSONResponseValidator` instance. * @param {Schema} schema Optional. JSON schema to validate the response against. * @param {string} missingJsonFeedback Optional. Custom feedback to give when no JSON is returned. * @param {string} errorFeedback Optional. Custom feedback prefix to use when schema errors are detected. */ constructor(schema, missingJsonFeedback, errorFeedback) { this.schema = schema; this.missingJsonFeedback = missingJsonFeedback ?? 'No valid JSON objects were found in the response. Return a valid JSON object.'; this.errorFeedback = errorFeedback ?? 'The JSON returned had errors. Apply these fixes:'; } /** * Feedback prefix given when schema errors are detected. */ errorFeedback; /** * Feedback given when no JSON is returned. */ missingJsonFeedback; /** * JSON schema to validate the response against. */ schema; /** * Validates a response to a prompt. * @param {TurnContext} context Context for the current turn of conversation with the user. * @param {Memory} memory An interface for accessing state values. * @param {Tokenizer} tokenizer Tokenizer to use for encoding and decoding text. * @param {PromptResponse<string>} response Response to validate. * @param {number} remaining_attempts Number of remaining attempts to validate the response. * @returns {Promise<Validation<TValue>>} A `Validation` object. */ validateResponse(context, memory, tokenizer, response, remaining_attempts) { const message = response.message; const text = message.content ?? ''; // Parse the response text const parsed = Response_1.Response.parseAllObjects(text); if (parsed.length == 0) { return Promise.resolve({ type: 'Validation', valid: false, feedback: this.missingJsonFeedback }); } // Validate the response against the schema if (this.schema) { let errors; const validator = new jsonschema_1.Validator(); for (let i = parsed.length - 1; i >= 0; i--) { const obj = Response_1.Response.removeEmptyValuesFromObject(parsed[i]); const result = validator.validate(obj, this.schema); if (result.valid) { return Promise.resolve({ type: 'Validation', valid: true, value: obj }); } else if (!errors) { errors = result.errors; } } return Promise.resolve({ type: 'Validation', valid: false, feedback: `${this.errorFeedback}\n${errors.map((e) => this.getErrorFix(e)).join('\n')}` }); } else { // Return the last object return Promise.resolve({ type: 'Validation', valid: true, value: parsed[parsed.length - 1] }); } } /** * @private * @param {ValidationError} error Error in the JSON object * @returns {string} How to fix the given error. */ getErrorFix(error) { // Get argument as a string let arg; if (Array.isArray(error.argument)) { arg = error.argument.join(','); } else if (typeof error.argument === 'object') { arg = JSON.stringify(error.argument); } else { arg = error.argument.toString(); } switch (error.name) { case 'type': // field is of the wrong type return `convert "${error.property}" to a ${arg}`; case 'anyOf': // field is not one of the allowed types return `convert "${error.property}" to one of the allowed types in the provided schema.`; case 'additionalProperties': // field has an extra property return `remove the "${arg}" property from ${error.property == 'instance' ? 'the JSON object' : `"${error.property}"`}`; case 'required': // field is missing a required property return `add the "${arg}" property to ${error.property == 'instance' ? 'the JSON object' : `"${error.property}"`}`; // TODO: jsonschema does not validate formats by default. https://github.com/microsoft/teams-ai/issues/1080 case 'format': // field is not in the correct format return `change the "${error.property}" property to be a ${arg}`; case 'uniqueItems': // field has duplicate items return `remove all duplicate items from "${error.property}"`; case 'enum': // field is not one of the allowed values arg = error.message.split(':')[1].trim(); return `change the "${error.property}" property to be one of these values: ${arg}`; case 'const': // field is not the correct value return `change the "${error.property}" property to be ${arg}`; default: return `"${error.property}" ${error.message}. Fix that`; } } } exports.JSONResponseValidator = JSONResponseValidator; //# sourceMappingURL=JSONResponseValidator.js.map