Conversation Logging feature enables you to register interactions between user and conversational agent (bot), bringing option to obfuscate sensitive data (both input and output). JAICF provides several abstractions and default implementations to solve conversation logging issue.
val templateBot = BotEngine(
model = MainScenario.model,
activators = arrayOf(RegexActivator),
conversationLoggers = arrayOf(
Slf4jConversationLogger(),
JaicpConversationLogger(accessToken)
)
)
How does it work?
Once JAICF receives a BotRequest
, it creates a LoggingContext
internal object that collects information about request’s input, selected activation (state and activation context) and all reactions generated by your dialogue scenario. When request processing is finished, JAICF fires the logging of the collected data.
val reactionsLogger = object : ConversationLogger(logObfuscators = emptyList()) {
override fun doLog(loggingContext: LoggingContext) {
println("Our reactions are: ${loggingContext.reactions}")
}
}
Reaction
A reaction object is a result of performing channel’s reaction. Every function of the base Reactions
(say, image, buttons, go and changeState) creates and registers the resulting Reaction
to the current logging context.
state("Hello") {
activators {
intent("/start")
}
action {
reactions.say("Hello there!") // Creates SayReaction and stores it to the LoggingContext
}
}
ConversationLogger
It’s the main abstraction for an object, that registers interactions between user and bot. Implementations of this abstraction should override only single method doLog
, having LoggingContext
as argument that contains necessary information regarding user’s query processing.
val historyTellingLogger = object : ConversationLogger(logObfuscators = emptyList()) {
override fun doLog(loggingContext: LoggingContext) {
println("""
I was resting in state ${loggingContext.firstState}, then someone sent me ${loggingContext.input}.
I decided to let ${loggingContext.activationContext?.activation?.state} handle this query,
and it all messed up and I reacted with ${loggingContext.reactions}.
""".trimIndent())
}
}
ConversationLogger
expects a list of log obfuscators as a property. Log obfuscators obfuscates LoggingContext
data before doLog
method is called. Thus doLog
method always receives an obfuscated LoggingContext
.
ConversationLogObfuscator
This abstraction enables you to hide sensitive data before it’s logged.
val numberObfuscator = object : ConversationLogObfuscator {
override fun obfuscateInput(loggingContext: LoggingContext) = loggingContext.input.map { char ->
if (char.isDigit()) '*'
else char
}.joinToString("")
}
Once request is processed and all reactions are created, JAICF obfuscates BotRequest input
and Reactions
.
Ready to use implementations
You may take a look at Slf4jConversationLogger
or JaicpConversationLogger
implementations before creating a new custom one, or use existing ones.
Slf4J
Slf4jConversationLogger
utilises Slf4J logging engine that can be enabled by placing logback.xml
to the resources
folder of your project. Please learn more about Logback and Slf4J.
JAICP
JaicpConversationLogger
automates logging of users’ inputs and reactions to the JAICP logging system.
CAILA NER obfuscator
There is also a built-in implementation of ConversationLogObfuscator
for CAILA NLU - CailaNamedEntityObfuscator
that either hides all found entities in request, or hides only entities from list given.