fix: el NLU respeta los modulos del perfil
Los menus se filtraban por modulo pero el texto libre no: un perfil limitado a pluviometria podia escribir "registrar ausentismo" y el NLU lo llevaba igual. El mismo agujero que ya cerramos con las fincas. moduloDeFlow() decide por convencion de nombre a que modulo pertenece cada flow —'modulo' explicito manda— y se aplica en dos puntos: el catalogo que ve el modelo llega filtrado, y el ruteo verifica igual la clave devuelta por si el modelo alucina una que no le ofrecieron. Lo permitido sigue directo: "subir pluviometria" cae en la fecha con un solo mensaje, "subir labores diarias" arranca el flujo. Cinco casos nuevos. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
9ae4b0dee3
commit
6c524a39ed
@@ -212,6 +212,44 @@ $get = array_values(array_filter(capturas(), fn($c) => str_contains($c['peticion
|
||||
check('la entity resolvió el grupo en la URL', $get['query']['grupo'] ?? null, '5');
|
||||
check('y la consulta dice quién pregunta', $get['query']['wa'] ?? null, '57300NLU');
|
||||
|
||||
// ════ 8. NLU coherente con los módulos del perfil ═════════════════════════════
|
||||
echo "\nNLU — respeta los módulos habilitados\n";
|
||||
|
||||
// Este número solo puede cargar pluviometría
|
||||
fakePhone('57300SOLOPLUVIO', null, 0);
|
||||
FakeDb::$phones['57300SOLOPLUVIO']['modulos_json'] = json_encode(['carga' => ['pluviometria']]);
|
||||
|
||||
$ctx = contexto('57300SOLOPLUVIO');
|
||||
$id = ConversationContext::getOrCreate(1, '57300SOLOPLUVIO')['id'];
|
||||
ConversationContext::updateMetadata($id, ['finca' => ['finca_id' => '4', 'finca_label' => 'REPOSO']]);
|
||||
ConversationContext::updateNode($id, '__greeted');
|
||||
|
||||
// "subir pluviometría" → directo a la fecha, un solo mensaje
|
||||
AiBot::$respuestas = [['action' => 'route', 'key' => 'registrar_pluviometria']];
|
||||
$r = NormalBot::process($co, $ctx, 'subir pluviometría');
|
||||
check('"subir pluviometría" va de una a la fecha', str_contains(textoDe($r), 'De qué fecha'));
|
||||
check('el NLU recibió su alcance de módulos', AiBot::$modulosRecibidos, ['pluviometria']);
|
||||
|
||||
// El modelo devuelve una clave fuera del alcance: el guard la corta
|
||||
ConversationContext::updateNode($id, '__greeted');
|
||||
ConversationContext::updateMetadata($id, ['finca' => ['finca_id' => '4', 'finca_label' => 'REPOSO']]);
|
||||
WhatsAppSender::$enviados = [];
|
||||
AiBot::$respuestas = [['action' => 'route', 'key' => 'registrar_ausentismo']];
|
||||
$r = NormalBot::process($co, $ctx, 'registrar ausentismo');
|
||||
check('un módulo vetado no ejecuta el flujo', !str_contains(textoDe($r), 'nombre o documento'));
|
||||
check('avisa que no entendió',
|
||||
str_contains(WhatsAppSender::$enviados[0]['text'] ?? '', 'No estoy seguro'));
|
||||
|
||||
// Sin restricción, "subir labores diarias" también entra directo
|
||||
$ctx = contexto('57300LABORNLU');
|
||||
$id = ConversationContext::getOrCreate(1, '57300LABORNLU')['id'];
|
||||
ConversationContext::updateMetadata($id, ['finca' => ['finca_id' => '4', 'finca_label' => 'REPOSO']]);
|
||||
ConversationContext::updateNode($id, '__greeted');
|
||||
AiBot::$respuestas = [['action' => 'route', 'key' => 'registrar_labor']];
|
||||
$r = NormalBot::process($co, $ctx, 'subir labores diarias');
|
||||
check('"subir labores diarias" arranca el flujo directo', str_contains(textoDe($r), 'De qué fecha es la labor'));
|
||||
capturas();
|
||||
|
||||
// ════ Resultado ═══════════════════════════════════════════════════════════════
|
||||
echo "\n" . ($GLOBALS['fallas'] ? "{$GLOBALS['fallas']} falla(s)\n" : "Todos los flujos ejecutan de punta a punta\n");
|
||||
exit($GLOBALS['fallas'] ? 1 : 0);
|
||||
|
||||
Reference in New Issue
Block a user