fix: match fuzzy de label en dynamic_list y collecting mid-flow
- handleDynamicList: usa str_contains bilateral para que "mantenimiento plateo" coincida con label "Plateo" (el NLU suele incluir palabras extra) - handleCollectingInput: si el texto transcrito no es un ID válido, intenta match fuzzy contra __label_map guardado en el estado collecting - handleDynamicList: guarda __label_map en el estado collecting para que mid-flow audio pueda auto-seleccionar sin ID exacto Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
3d04be14bc
commit
976f61b682
+32
-9
@@ -139,16 +139,31 @@ class NormalBot
|
|||||||
$key = $col['meta_key'] ?? '';
|
$key = $col['meta_key'] ?? '';
|
||||||
$nextNode = $col['next_node'] ?? null;
|
$nextNode = $col['next_node'] ?? null;
|
||||||
$validIds = $col['__valid_ids'] ?? null;
|
$validIds = $col['__valid_ids'] ?? null;
|
||||||
|
$labelMap = $col['__label_map'] ?? [];
|
||||||
|
|
||||||
if ($validIds !== null && !in_array(trim($input), $validIds, true)) {
|
$resolved = trim($input);
|
||||||
return self::sendText(
|
if ($validIds !== null && !in_array($resolved, $validIds, true)) {
|
||||||
'⚠️ Por favor selecciona una opción válida de la lista.',
|
// Intento de match por label (útil cuando viene texto transcrito de audio)
|
||||||
$context['from'], $company
|
$inputNorm = self::normalize($resolved);
|
||||||
);
|
$matched = null;
|
||||||
|
foreach ($labelMap as $label => $id) {
|
||||||
|
$lNorm = self::normalize((string)$label);
|
||||||
|
if ($lNorm === $inputNorm || str_contains($inputNorm, $lNorm) || str_contains($lNorm, $inputNorm)) {
|
||||||
|
$matched = (string)$id;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($matched === null) {
|
||||||
|
return self::sendText(
|
||||||
|
'⚠️ Por favor selecciona una opción válida de la lista.',
|
||||||
|
$context['from'], $company
|
||||||
|
);
|
||||||
|
}
|
||||||
|
$resolved = $matched;
|
||||||
}
|
}
|
||||||
|
|
||||||
$formData = $meta[$group] ?? [];
|
$formData = $meta[$group] ?? [];
|
||||||
$formData[$key] = trim($input);
|
$formData[$key] = $resolved;
|
||||||
$meta[$group] = $formData;
|
$meta[$group] = $formData;
|
||||||
unset($meta['collecting']);
|
unset($meta['collecting']);
|
||||||
ConversationContext::updateMetadata($ctxId, $meta);
|
ConversationContext::updateMetadata($ctxId, $meta);
|
||||||
@@ -198,6 +213,12 @@ class NormalBot
|
|||||||
$key = $flow['meta_key'] ?? '';
|
$key = $flow['meta_key'] ?? '';
|
||||||
$nextNode = $flow['next_node'] ?? null;
|
$nextNode = $flow['next_node'] ?? null;
|
||||||
|
|
||||||
|
// Mapa label → id para match fuzzy (usado tanto en auto-select como en collecting)
|
||||||
|
$labelMap = [];
|
||||||
|
foreach ($items as $item) {
|
||||||
|
$labelMap[(string)($item[$labelField] ?? '')] = (string)($item[$valueField] ?? '');
|
||||||
|
}
|
||||||
|
|
||||||
// Si el NLU extrajo entities, intentar auto-seleccionar sin mostrar lista
|
// Si el NLU extrajo entities, intentar auto-seleccionar sin mostrar lista
|
||||||
$entities = $meta['__nlu_entities'] ?? [];
|
$entities = $meta['__nlu_entities'] ?? [];
|
||||||
unset($meta['__nlu_entities']);
|
unset($meta['__nlu_entities']);
|
||||||
@@ -205,9 +226,10 @@ class NormalBot
|
|||||||
$matchedId = null;
|
$matchedId = null;
|
||||||
foreach ($entities as $ev) {
|
foreach ($entities as $ev) {
|
||||||
$evNorm = self::normalize((string)$ev);
|
$evNorm = self::normalize((string)$ev);
|
||||||
foreach ($items as $item) {
|
foreach ($labelMap as $label => $id) {
|
||||||
if (self::normalize((string)($item[$labelField] ?? '')) === $evNorm) {
|
$lNorm = self::normalize($label);
|
||||||
$matchedId = (string)($item[$valueField] ?? '');
|
if ($lNorm === $evNorm || str_contains($evNorm, $lNorm) || str_contains($lNorm, $evNorm)) {
|
||||||
|
$matchedId = $id;
|
||||||
break 2;
|
break 2;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -238,6 +260,7 @@ class NormalBot
|
|||||||
'meta_key' => $key,
|
'meta_key' => $key,
|
||||||
'next_node' => $nextNode,
|
'next_node' => $nextNode,
|
||||||
'__valid_ids' => array_column($items, $valueField),
|
'__valid_ids' => array_column($items, $valueField),
|
||||||
|
'__label_map' => $labelMap,
|
||||||
];
|
];
|
||||||
ConversationContext::updateMetadata($ctxId, $meta);
|
ConversationContext::updateMetadata($ctxId, $meta);
|
||||||
ConversationContext::updateNode($ctxId, 'collecting');
|
ConversationContext::updateNode($ctxId, 'collecting');
|
||||||
|
|||||||
Reference in New Issue
Block a user