modularizado de prompts

This commit is contained in:
Lucas Tettamanti
2026-01-25 20:51:33 -03:00
parent b91ece867b
commit a489ec66a2
43 changed files with 5408 additions and 89 deletions

View 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,
};
}