Skip to content

Primitivas para acceder a BotResultValue desde Botlang

Descripción

Estas primitivas permiten inspeccionar objetos BotResultValue que retornan módulos externos de Python desde el código Botlang.

⚠️ Caso de uso

Estas primitivas están diseñadas para trabajar con BotResultValue que provienen de módulos externos escritos en Python, como:

  • Módulos de IA (adereso-ai, watson, etc.)
  • Integraciones externas
  • Funciones personalizadas que retornan BotResultValue

NO están diseñadas para inspeccionar node-result creados dentro del código Botlang (esos ya tienen acceso directo a sus componentes).

Primitivas disponibles

result-message

Extrae el mensaje de un BotResultValue.

1
2
(define bot-result (some-external-function context))
(define message (result-message bot-result))

result-data

Extrae el contexto/data de un BotResultValue.

1
2
(define bot-result (some-external-function context))
(define data (result-data bot-result))

result-next-node

Extrae el nodo siguiente de un BotResultValue.

1
2
(define bot-result (some-external-function context))
(define next (result-next-node bot-result))

result-action

Extrae la acción si el siguiente nodo es un TerminalNode.

1
2
3
(define bot-result (some-external-function context))
(define action (result-action bot-result))
; Retorna el string de acción o nil

terminal-node-action

Extrae el string de acción directamente de un TerminalNode.

1
2
3
4
5
6
7
(define bot-result (some-external-function context))
(define next-node (result-next-node bot-result))

(if (terminal-node? next-node)
    (define action (terminal-node-action next-node))
    ; action ahora contiene el string, ej: "CLOSE_TICKET"
)

dialog-node-name

Extrae el nombre directamente de un DialogNode.

1
2
3
4
5
6
7
(define bot-result (some-external-function context))
(define next-node (result-next-node bot-result))

(if (dialog-node? next-node)
    (define name (dialog-node-name next-node))
    ; name ahora contiene el nombre del nodo
)

terminal-node?

Verifica si un nodo es un TerminalNode.

1
2
3
(define bot-result (some-external-function context))
(define next (result-next-node bot-result))
(terminal-node? next)  ; #t o #f

dialog-node?

Verifica si un nodo es un DialogNode.

1
2
3
(define bot-result (some-external-function context))
(define next (result-next-node bot-result))
(dialog-node? next)  ; #t o #f

Ejemplo real: Adereso AI

Opción 1: Usando result-action (directamente del BotResultValue)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
(require "adereso-studio")

(define ai-handler-node
    (bot-node (context message)
        (begin
            ; Llamar al módulo de AI que retorna un BotResultValue
            (define ai-result (ask-studio "3.0" context message some-node))

            ; Extraer la acción del resultado
            (define action (result-action ai-result))

            ; Tomar decisiones basadas en la acción
            (cond
                [(equal? action "CLOSE_TICKET")
                    (begin
                        (put! context "reason" "AI closed ticket")
                        ; Retornar el resultado del AI directamente
                        ai-result
                    )
                ]
                [(equal? action "ASSIGN_TO_CM")
                    (begin
                        (put! context "escalated" #t)
                        ; Modificar el mensaje antes de retornar
                        (node-result
                            (result-data ai-result)
                            "Escalando a CM..."
                            (result-next-node ai-result)
                        )
                    )
                ]
                [else
                    ; Continuar con el flujo normal
                    ai-result
                ]
            )
        )
    )
)

Opción 2: Usando terminal-node-action (desde el nodo extraído)

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
(require "adereso-studio")

(define ai-handler-node-v2
    (bot-node (context message)
        (begin
            ; Llamar al módulo de AI
            (define ai-result (ask-studio "3.0" context message some-node))

            ; Extraer el nodo siguiente
            (define next-node (result-next-node ai-result))

            ; Verificar si es un terminal node y extraer la acción
            (define action 
                (if (terminal-node? next-node)
                    (terminal-node-action next-node)
                    nil
                )
            )

            ; Guardar información para análisis
            (put! context "last-action" action)
            (put! context "is-terminal" (terminal-node? next-node))
            (put! context "is-dialog" (dialog-node? next-node))

            ; Tomar decisiones
            (cond
                [(equal? action "CLOSE_TICKET")
                    (node-result context "Cerrando ticket..." end-node)
                ]
                [(equal? action "ASSIGN_TO_CM")
                    (node-result context "Escalando..." transfer-node)
                ]
                [else ai-result]
            )
        )
    )
)

Ejemplo: Módulo personalizado

Si tienes un módulo Python personalizado:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
# En Python
class MyModule(ExternalModule):
    def __init__(self):
        super().__init__('my-module', {
            'process-data': self.process_data
        })

    def process_data(self, context, data):
        # Procesar datos...
        return BotResultValue(
            context,
            "Procesamiento completado",
            TerminalNode("DATA_PROCESSED")
        )

Puedes usarlo en Botlang:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
(require "my-module")

(define process-node
    (bot-node (context message)
        (begin
            ; Llamar al módulo que retorna BotResultValue
            (define result (process-data context message))

            ; Inspeccionar el resultado
            (define msg (result-message result))
            (define action (result-action result))

            ; Guardar información en contexto
            (put! context "last-action" action)
            (put! context "last-message" msg)

            ; Decidir qué hacer
            (if (equal? action "DATA_PROCESSED")
                (node-result context "Datos procesados con éxito" end-node)
                result  ; Retornar el resultado original
            )
        )
    )
)

Ejemplo: Logging y debugging

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
(require "adereso-studio")

(define debug-ai-node
    (bot-node (context message)
        (begin
            (define ai-result (ask-studio "3.0" context message next-node))

            ; Log de información para debugging
            (log-event "ai-response" (append 
                "Message: " (result-message ai-result)
                " | Action: " (str (result-action ai-result))
            ))

            ; Almacenar para análisis
            (put! context "ai-last-action" (result-action ai-result))
            (put! context "ai-last-message" (result-message ai-result))

            ; Retornar el resultado
            ai-result
        )
    )
)

Notas importantes

  1. Retornan nil: Si el argumento no es un BotResultValue, las funciones retornan nil
  2. result-action: Solo retorna un valor si el siguiente nodo es un TerminalNode
  3. Disponibilidad: Estas primitivas están disponibles automáticamente en todos los bots
  4. Caso de uso: Diseñadas para inspeccionar resultados de módulos externos, no node-result internos

Diferencia clave

NO hacer esto (no tiene sentido):

1
2
3
; Esto no es útil porque ya tienes acceso a los valores
(define my-result (node-result context "mensaje" end-node))
(define msg (result-message my-result))  ; Innecesario

SÍ hacer esto (caso de uso correcto):

1
2
3
; Inspeccionar resultado de módulo externo
(define ai-result (ask-studio "3.0" context message next-node))
(define action (result-action ai-result))  ; ✓ Útil para tomar decisiones