@llumiverse/core
Version:
Provide an universal API to LLMs. Support for existing LLMs can be added by writing a driver.
96 lines • 3.37 kB
JavaScript
;
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ValidationError = void 0;
exports.validateResult = validateResult;
const ajv_1 = require("ajv");
const ajv_formats_1 = __importDefault(require("ajv-formats"));
const json_js_1 = require("./json.js");
const resolver_js_1 = require("./resolver.js");
const ajv = new ajv_1.Ajv({
coerceTypes: 'array',
allowDate: true,
strict: false,
useDefaults: true,
removeAdditional: "failing"
});
//use ts ignore to avoid error with ESM and ajv-formats
// @ts-ignore This expression is not callable
(0, ajv_formats_1.default)(ajv);
class ValidationError extends Error {
code;
constructor(code, message) {
super(message);
this.code = code;
this.name = 'ValidationError';
}
}
exports.ValidationError = ValidationError;
function parseCompletionAsJson(data) {
let lastError;
for (const part of data) {
if (part.type === "text") {
const text = part.value.trim();
try {
return (0, json_js_1.extractAndParseJSON)(text);
}
catch (error) {
lastError = new ValidationError("json_error", error.message);
}
}
}
if (!lastError) {
lastError = new ValidationError("json_error", "No JSON compatible response found in completion result");
}
throw lastError;
}
function validateResult(data, schema) {
let json;
if (Array.isArray(data)) {
const jsonResults = data.filter(r => r.type === "json");
if (jsonResults.length > 0) {
json = jsonResults[0].value;
}
else {
try {
json = parseCompletionAsJson(data);
}
catch (error) {
throw new ValidationError("json_error", error.message);
}
}
}
else {
throw new Error("Data to validate must be an array");
}
const validate = ajv.compile(schema);
const valid = validate(json);
if (!valid && validate.errors) {
let errors = [];
for (const e of validate.errors) {
const path = e.instancePath.split("/").slice(1);
const value = (0, resolver_js_1.resolveField)(json, path);
const schemaPath = e.schemaPath.split("/").slice(1);
const schemaFieldFormat = (0, resolver_js_1.resolveField)(schema, schemaPath);
const schemaField = (0, resolver_js_1.resolveField)(schema, schemaPath.slice(0, -3));
//ignore date if empty or null
if (!value
&& ["date", "date-time"].includes(schemaFieldFormat)
&& !schemaField?.required?.includes(path[path.length - 1])) {
continue;
}
else {
errors.push(e);
}
}
//console.log("Errors", errors)
if (errors.length > 0) {
const errorsMessage = errors.map(e => `${e.instancePath}: ${e.message}\n${JSON.stringify(e.params)}`).join(",\n\n");
throw new ValidationError("validation_error", errorsMessage);
}
}
return [{ type: "json", value: json }];
}
//# sourceMappingURL=validation.js.map