Keep conversation context with watson - watson-conversation

In a Watson's conversation to keep the context, do I need to send only the conversation_id every request? or the entire context object?

You need to send back the conversation_id and the system part of the context. The conversation ID uniquely identifies the specific conversation. The metadata in the system info has details about how long the dialog has been going on (how many turns) and in which dialog node you are. See here in the IBM Watson Conversation service docs for more information about maintaining state.
The context object also includes the user-specified data. That part can be wiped out or newly set on each turn.
What you can do is to first copy over the entire context object, then manipulate the user-oriented parts.

Related

Whats the best way to generate ledger change Events that include the Transaction Command?

The goal is to generate events on every participating node when a state is changed that includes the business action that caused the change. In our case, Business Action maps to the Transaction command and provides the business intent or what the user is doing in business terms. So in our case, where we are modelling the lifecycle of a loan, an action might be to "Close" the loan.
We model Event at a state level as follows: Each Event encapsulates a Transaction Command and is uniquely identified by a (TxnHash, OutputIndex) and a created/consumed status.
We would prefer a polling mechanism to generate events on demand, but an asynch approach to generate events on ledger changes would be acceptable. Either way our challenge is in getting the Command from the Transaction.
We considered querying the States using the Vault Query API vaultQueryBy() for the polling solution (or vaultTrackBy() for the asynch Obvservalble Stream solution). We were able to create a flow that gets the txn for a state. This had to be done in a flow, as Corda deprecated the function that would have allowed us to do this in our Springboot client. In the client we use vaultQueryBy() to get a list of States. Then we call a flow that iterates over the states, gets txHash from each StateRef and then calls serviceHub.validatedTransactions.getTransaction(txHash) to get signedTransaction from which we can ultimately retrieve the Command. Is this the best or recommended approach?
Alternatively, we have also thought of generating events of the Transaction by querying for transactions and then building the Event for each input and output state in the transaction. If we go this route what's the best way to query transactions from the vault? Is there an Observable Stream-based option?
I assume this mapping of states to command is a common requirement for observers of the ledger because it is standard to drive contract logic off the transaction command and quite natural to have the command map to the user intent.
What is the best way to generate events that encapsulate the transaction command for each state created or consumed on the ledger?
If I understand correctly you're attempting to get a notified when certain types of ledger updates occur (open, approved, closed, etc).
First: Asynchronous notifications are best practice in Corda, polling should be avoided due to the added weight it puts on the node for constant querying and delays. Corda provides several mechanisms for Observables which you can use: https://docs.corda.net/api/kotlin/corda/net.corda.core.messaging/-corda-r-p-c-ops/vault-track-by.html
Second: Avoid querying transactions from the database as these are intended to be internal to the node. See this answer for background on why to avoid transaction querying. In general only tables that begin with "VAULT_*" are intended to be queried.
One way to solve your use case would be a "status" field which reflects the command that was used to produce the current state. For example: if a "Close" command was used to produce the state it's status field could be "closed". This way you could use the above vaultTrackBy to look at each state's status field and infer the action that occured.
Just to finish up on my comment: While the approach met the requirements, The problem with this solution is that we have to add and maintain our own code across all relevant states to capture transaction-level information that is already tracked by the platform. I would think a better solution would be for the platform to provide consumers access to transaction-level information (selectively perhaps) just as it does for states. After all, the transaction is, in part, a business/functional construct that is meaningful at the client application level. For example, If I am "transferring" a loan, that may be a complex business transaction that involves many input and output states and may be an important construct/notion for the client application to manage.

Reading list with Dialoglfow fulfillment from Real-Time Database

I am creating a chatbot using Dialogflow and Dialogflow's Inline Editor (for Cloud functions and Firebase database "Real-Time Database"). I will integrate this chatbot with Google Assistant.
I have to read a list from the database, wherein the list has several children, few of them have sub-children, and few of sub-children have sub-sub-children. Because the output is a list and consists long-text, it will take too long to speak all data at once. So I would like to output one child from the list and ask the user for permission (Yes/No) as "Do you want to read the next?". If the user says "Yes", I will continue reading likewise until the end. And if the user says "No", I will trigger an event. Asking for the permission from the user is true before reading a child, even sub-child, and even sub-sub-child.
The approach that I have taken involves creating a separate DB record for each user when they first request the list, to keep track of where they are in the list. When the user says yes, get user’s current item id from the database, get the next item in the list (return it to the user via agent.add) and then update the user’s DB record to the next item’s id and so on until the user reaches the end of the list. After agent.add(), ask for the permission from the user by agent.setFollowupEvent(). If the user says no, just reset/delete the DB record for that user.
Few questions I would like to ask:
How will I identify each user as an individual: by some id, session, or something else?
When I run the below code in return cloud function, agent.add is overridden by agent.setFollowupEvent. How do I stop this?
agent.add('I will print the list here!');
agent.setFollowupEvent('SOME_EVENT'); //invoking an intent to ask for the permission.
You have a few issues you're trying to raise here, in addition to the one you're dealing with. Looking at each:
How can I stop setFollowupEvent() from overriding the message I've set?
You don't. The entire point of setFollowupEvent() is to switch to a different Intent instead of the one that is currently being processed.
Most of the time you think you want setFollowupEvent(), you probably don't. Don't use it.
So how can I add the question at the end of what I'm saying?
Just ask it.
Really, it is that easy.
You can either include it in the string you're sending to agent.add(), or (depending on the details), you can do a second add() with the prompt.
But don't I need to trigger an Intent to get the answer?
No. That isn't what an Intent is for.
Intents capture what the user is saying, not what you are asking or what your agent is doing. Your fulfillment does something based on both the Intent that is triggered as well as the rest of the state that you know about the conversation. But the Intent is just one bit of that information.
You mentioned user state. How can I keep track of the user state during the conversation?
Since it looks like you're using the dialogflow-fulfillment library, the easiest way is to store your state in the parameters in a Context with a very long lifespan (or that you keep renewing).
So the first time your fulfillment is triggered, you can check the Context. If the Context or ID aren't there, then you would generate a random user ID and store it in the Context. Subsequently, you would use this ID to look up the user's information in the real time database.
If I'm doing this work, do I need the database?
Nope! If you are just storing a little bit of information about the user, and the information will just last the lifespan of the conversation, you can store all of it in Context parameters directly. You do need to make sure that these parameter names don't conflict with any parameters that your Intents have, but otherwise these will last las long as the Context does.
If you need to store information about this person in between conversations, then you will need to look into other methods. There is a User ID available for Actions, but this is deprecated and scheduled to be removed. There are also session storage and user storage fields that the Assistant makes available, but these are a little tricker to use using the dialogflow-fulfillment library if you don't need them.

Watson conversation reset conversation

There is any way to tell to watson that he sould reset the conversation "after this point everty asked will be just like conversation_start"?
tks
Watson conversation is stateless. So it doesn't know anything about where you are in the conversation without the context object.
To reset the conversation, you just don't send the context object, and it will generate a new one.
Or let's say you are in a process flow, and want to reset to a particular point. Just take a copy of the context object at that point in time. Then use that to rollback.
This is assuming that your application layer hasn't done anything outside of conversation which would be related to the rollback.

Intent scopes on Alexa skill

I'm implementing an Alexa search skill for a website. My question is that there is some kind of possibilities to give intents some kind of scopes, so built in Intents could be reused?
I mean, for ex. the AMAZON.YestIntent to have different functionalities on different situations.
You can handle this in your intent handler. You can save context information in the session or a database if you are using one. Then in the intent handler, test the session or DB data to determine which response to take.
For example, in the Who's On First? Baseball Skit skill, the dialog between the user and Alexa is about 85 lines long. The user can say "who?" at several different places in the dialog, and Alexa needs to respond differently depending upon which line of the dialog they are at. To handle this, I simply save the line number in the session. Then when an intent is called, the intent handler gets the line number session variable, uses it to select the appropriate response, and increments it and passes it along in the session for the next line.
It really depends on the complexity of your skill, the accepted answer is a perfectly correct implementation for a simple flow and it starts to address keeping state tied to the session.
If your skill is more complex and you're using Node.js, I would suggest using the official SDK which offers this functionality out of the box:
https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs
The state management allows you to define which intents should be handled in each state and the rest can be passed to a context-specific handler. More information is here:
https://github.com/alexa/alexa-skills-kit-sdk-for-nodejs#making-skill-state-management-simpler
The state management takes a little getting used to, but once you have used it, you won't go back because of the control it offers you over the experience.

Adding notifications to my web app

I'm creating a chrome extension that allows users to chat with one another. I've finished the basic implementation and want to add notifications that tell a user if they've received a new chat message since the last time they were connected. I have an idea of how I want to implement it but need input on whether it seems feasible and suitable.
Basically, my database is structured so that there is a list of users and chatrooms. Each user has a section called chats which lists all the names of the chatrooms they're in:
What I plan to do is the following: In every chat under each user's chats section, instead of setting its value to true, I set it to the last time they disconnected. Then in each chatroom, I add another field after user2 called timeLastMessageSent and always update it to the current time a new message is sent.
With that information, every time a user connects I'll loop through the chatroom's listed in their chats section and see if the value of timeLastMessageSent is higher than their last disconnect time, which means a message was sent while they were away and I can add some sort of notification that they have a new message.
I'm relatively new to firebase so if anyone with more experience can tell me what they think of my idea I'd really appreciate it. Is this idea feasible? Am I approaching the problem correctly? What sort of commands should I get familiar with to achieve this?

Resources