modularizado de prompts
This commit is contained in:
283
src/modules/3-turn-engine/nlu/schemas.js
Normal file
283
src/modules/3-turn-engine/nlu/schemas.js
Normal file
@@ -0,0 +1,283 @@
|
||||
/**
|
||||
* Schemas JSON para validación de respuestas NLU
|
||||
*/
|
||||
|
||||
import Ajv from "ajv";
|
||||
|
||||
const ajv = new Ajv({ allErrors: true, strict: true });
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// Schema: Router
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
export const RouterSchema = {
|
||||
$id: "Router",
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
required: ["domain"],
|
||||
properties: {
|
||||
domain: {
|
||||
type: "string",
|
||||
enum: ["greeting", "orders", "shipping", "payment", "browse", "other"],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const validateRouter = ajv.compile(RouterSchema);
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// Schema: Greeting
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
export const GreetingSchema = {
|
||||
$id: "Greeting",
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
required: ["intent", "reply"],
|
||||
properties: {
|
||||
intent: { type: "string", enum: ["greeting"] },
|
||||
reply: { type: "string", minLength: 1 },
|
||||
},
|
||||
};
|
||||
|
||||
export const validateGreeting = ajv.compile(GreetingSchema);
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// Schema: Orders
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
export const OrdersSchema = {
|
||||
$id: "Orders",
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
required: ["intent", "confidence"],
|
||||
properties: {
|
||||
intent: {
|
||||
type: "string",
|
||||
enum: ["add_to_cart", "remove_from_cart", "view_cart", "confirm_order"],
|
||||
},
|
||||
confidence: { type: "number", minimum: 0, maximum: 1 },
|
||||
items: {
|
||||
anyOf: [
|
||||
{ type: "null" },
|
||||
{
|
||||
type: "array",
|
||||
items: {
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
required: ["product_query"],
|
||||
properties: {
|
||||
product_query: { type: "string", minLength: 1 },
|
||||
quantity: { anyOf: [{ type: "number" }, { type: "null" }] },
|
||||
unit: { anyOf: [{ type: "string", enum: ["kg", "g", "unidad"] }, { type: "null" }] },
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
product_query: { anyOf: [{ type: "string" }, { type: "null" }] },
|
||||
quantity: { anyOf: [{ type: "number" }, { type: "null" }] },
|
||||
unit: { anyOf: [{ type: "string", enum: ["kg", "g", "unidad"] }, { type: "null" }] },
|
||||
},
|
||||
};
|
||||
|
||||
export const validateOrders = ajv.compile(OrdersSchema);
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// Schema: Shipping
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
export const ShippingSchema = {
|
||||
$id: "Shipping",
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
required: ["intent"],
|
||||
properties: {
|
||||
intent: {
|
||||
type: "string",
|
||||
enum: ["select_shipping", "provide_address"],
|
||||
},
|
||||
shipping_method: {
|
||||
anyOf: [{ type: "string", enum: ["delivery", "pickup"] }, { type: "null" }],
|
||||
},
|
||||
address: { anyOf: [{ type: "string" }, { type: "null" }] },
|
||||
},
|
||||
};
|
||||
|
||||
export const validateShipping = ajv.compile(ShippingSchema);
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// Schema: Payment
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
export const PaymentSchema = {
|
||||
$id: "Payment",
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
required: ["intent"],
|
||||
properties: {
|
||||
intent: {
|
||||
type: "string",
|
||||
enum: ["select_payment"],
|
||||
},
|
||||
payment_method: {
|
||||
anyOf: [{ type: "string", enum: ["cash", "link"] }, { type: "null" }],
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export const validatePayment = ajv.compile(PaymentSchema);
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// Schema: Browse
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
export const BrowseSchema = {
|
||||
$id: "Browse",
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
required: ["intent"],
|
||||
properties: {
|
||||
intent: {
|
||||
type: "string",
|
||||
enum: ["price_query", "browse", "recommend"],
|
||||
},
|
||||
product_query: { anyOf: [{ type: "string" }, { type: "null" }] },
|
||||
people_count: { anyOf: [{ type: "number" }, { type: "null" }] },
|
||||
event_type: { anyOf: [{ type: "string" }, { type: "null" }] },
|
||||
},
|
||||
};
|
||||
|
||||
export const validateBrowse = ajv.compile(BrowseSchema);
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// Schema: NLU Unificado (output final)
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
export const UnifiedNluSchema = {
|
||||
$id: "UnifiedNlu",
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
required: ["intent", "confidence", "language", "entities", "needs"],
|
||||
properties: {
|
||||
intent: {
|
||||
type: "string",
|
||||
enum: [
|
||||
"price_query", "browse", "add_to_cart", "remove_from_cart",
|
||||
"checkout", "confirm_order", "select_payment", "select_shipping",
|
||||
"provide_address", "greeting", "recommend", "view_cart", "other"
|
||||
],
|
||||
},
|
||||
confidence: { type: "number", minimum: 0, maximum: 1 },
|
||||
language: { type: "string" },
|
||||
entities: {
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
required: ["product_query", "quantity", "unit", "selection", "attributes", "preparation", "items"],
|
||||
properties: {
|
||||
product_query: { anyOf: [{ type: "string" }, { type: "null" }] },
|
||||
quantity: { anyOf: [{ type: "number" }, { type: "null" }] },
|
||||
unit: { anyOf: [{ type: "string", enum: ["kg", "g", "unidad"] }, { type: "null" }] },
|
||||
selection: {
|
||||
anyOf: [
|
||||
{ type: "null" },
|
||||
{
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
required: ["type", "value"],
|
||||
properties: {
|
||||
type: { type: "string", enum: ["index", "text", "sku"] },
|
||||
value: { type: "string", minLength: 1 },
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
attributes: { type: "array", items: { type: "string" } },
|
||||
preparation: { type: "array", items: { type: "string" } },
|
||||
payment_method: { anyOf: [{ type: "string", enum: ["cash", "link"] }, { type: "null" }] },
|
||||
shipping_method: { anyOf: [{ type: "string", enum: ["delivery", "pickup"] }, { type: "null" }] },
|
||||
address: { anyOf: [{ type: "string" }, { type: "null" }] },
|
||||
items: {
|
||||
anyOf: [
|
||||
{ type: "null" },
|
||||
{
|
||||
type: "array",
|
||||
items: {
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
required: ["product_query"],
|
||||
properties: {
|
||||
product_query: { type: "string", minLength: 1 },
|
||||
quantity: { anyOf: [{ type: "number" }, { type: "null" }] },
|
||||
unit: { anyOf: [{ type: "string", enum: ["kg", "g", "unidad"] }, { type: "null" }] },
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
},
|
||||
// Browse-specific
|
||||
people_count: { anyOf: [{ type: "number" }, { type: "null" }] },
|
||||
event_type: { anyOf: [{ type: "string" }, { type: "null" }] },
|
||||
},
|
||||
},
|
||||
needs: {
|
||||
type: "object",
|
||||
additionalProperties: false,
|
||||
required: ["catalog_lookup", "knowledge_lookup"],
|
||||
properties: {
|
||||
catalog_lookup: { type: "boolean" },
|
||||
knowledge_lookup: { type: "boolean" },
|
||||
},
|
||||
},
|
||||
// Greeting-specific: reply del LLM
|
||||
reply: { anyOf: [{ type: "string" }, { type: "null" }] },
|
||||
},
|
||||
};
|
||||
|
||||
export const validateUnifiedNlu = ajv.compile(UnifiedNluSchema);
|
||||
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
// Helpers
|
||||
// ─────────────────────────────────────────────────────────────
|
||||
|
||||
/**
|
||||
* Obtiene errores de validación formateados
|
||||
*/
|
||||
export function getValidationErrors(validate) {
|
||||
const errors = validate.errors || [];
|
||||
return errors.map((e) => ({
|
||||
path: e.instancePath,
|
||||
message: e.message,
|
||||
params: e.params,
|
||||
}));
|
||||
}
|
||||
|
||||
/**
|
||||
* Crea un NLU unificado vacío (fallback)
|
||||
*/
|
||||
export function createEmptyNlu() {
|
||||
return {
|
||||
intent: "other",
|
||||
confidence: 0,
|
||||
language: "es-AR",
|
||||
entities: {
|
||||
product_query: null,
|
||||
quantity: null,
|
||||
unit: null,
|
||||
selection: null,
|
||||
attributes: [],
|
||||
preparation: [],
|
||||
payment_method: null,
|
||||
shipping_method: null,
|
||||
address: null,
|
||||
items: null,
|
||||
people_count: null,
|
||||
event_type: null,
|
||||
},
|
||||
needs: {
|
||||
catalog_lookup: false,
|
||||
knowledge_lookup: false,
|
||||
},
|
||||
reply: null,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user