All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.justai.jaicf.context.ActionContext.kt Maven / Gradle / Ivy

package com.justai.jaicf.context

import com.justai.jaicf.api.BotRequest
import com.justai.jaicf.generic.ActivatorTypeToken
import com.justai.jaicf.generic.ChannelTypeToken
import com.justai.jaicf.generic.ContextTypeToken
import com.justai.jaicf.helpers.action.safeCast
import com.justai.jaicf.helpers.action.smartRandom
import com.justai.jaicf.logging.ButtonsReaction
import com.justai.jaicf.model.state.StatePath
import com.justai.jaicf.reactions.Reactions
import kotlin.random.Random

/**
 * The context of the request execution. Every action code block of the scenario is executed in this context.
 * Contains properties related to the user's data, activator's details, request's details and reactions API.
 * Also provides some helpful methods for response building.
 *
 * @property context a [BotContext] instance that contains user-related and dialogue state data
 * @property activator a particular [ActivatorContext] of the activator that handled the user's request
 * @property request a particular channel-related [BotRequest] that contains request's details
 * @property reactions a particular channel-related [Reactions] that contains methods for building and sending a response
 *
 * @see [BotContext]
 * @see [ActivatorContext]
 * @see [BotRequest]
 * @see [Reactions]
 */
open class ActionContext(
    open val context: BotContext,
    open val activator: A,
    open val request: B,
    open val reactions: R
) {

    /**
     * Returns random element.
     * Works as a smart random preserving previous calls results to guarantee that there are no two equal results in two consecutive calls.
     * @param elements a list of elements to select random from
     * @return a random element
     */
    fun  random(elements: List) = elements[smartRandom(elements.size, this) % elements.size]

    /**
     * Returns random element.
     * @param elements a vararg of elements to select random from
     * @return a random element
     */
    fun  random(vararg elements: T) = random(elements.asList())

    /**
     * Returns random [Int] between 0 (inclusive) and [max] (exclusive).
     * Works as a smart random preserving previous calls results to guarantee that there are no two equal results in two consecutive calls.
     * @param max an upper bound
     * @return a random [Int]
     */
    open fun random(max: Int) = smartRandom(max, this)

    /**
     * Returns random [Int] between [min] (inclusive) and [max] (exclusive).
     * Works as a usual Random.nextInt
     *
     * @param min a lower bound
     * @param max an upper bound
     * @return a random [Int]
     */
    open fun random(min: Int, max: Int) = Random.nextInt(min, max)

    /**
     * A helper function that puts a randomized phrase into the response.
     * Utilizes smart random function to guarantee that there are no two equal phrases was returned to the user in two consecutive requests.
     * @param texts a vararg of texts to select random from
     */
    fun Reactions.sayRandom(vararg texts: String) = sayRandom(texts.asList())

    /**
     * A helper function that puts a randomized phrase into the response.
     * Utilizes smart random function to guarantee that there are no two equal phrases was returned to the user in two consecutive requests.
     * @param texts a list of String to select random from
     */
    fun Reactions.sayRandom(texts: List) = say(random(texts))

    infix fun ButtonsReaction?.toStates(states: List) {
        this?.buttons?.zip(states)?.forEach { (text, state) ->
            context.dialogContext.transitions[text.toLowerCase()] =
                StatePath.parse(context.dialogContext.currentState).resolve(state).toString()
        }
    }


    operator fun  ActivatorTypeToken.invoke(action: ActionContext.() -> T): T? =
        safeCast(this)?.run(action)

    operator fun  ChannelTypeToken.invoke(action: ActionContext.() -> T): T? =
        safeCast(this)?.run(action)

    operator fun  ContextTypeToken.invoke(action: ActionContext.() -> T): T? =
        safeCast(this)?.run(action)
}

typealias DefaultActionContext = ActionContext




© 2015 - 2024 Weber Informatics LLC | Privacy Policy