2

Using Dialogflow's Node Fulfillment SDK, I thought one could programmatically set and delete contexts, and extract parameters from within them.

I'm trying to collect values for multiple parameters, and they can come in on multiple passes to the same intent. The following code runs within the intent handler:

contextParams = agent.context.get("seek-create-params-context").parameters;
currentParams = agent.parameters;

// merge will look for required params from both current and context
newParameters = merge(currentParams, contextParams); 

agent.context.set({
 name: "seek-create-params-context",
 lifespan: 1,
 parameters: newParameters
});

It extracts the params that were passed in on the previous interaction, merges it with the newly available params, and reset the context with the new set of available params.

However, right now, on each pass, "seek-create-params-context" doesn't contain what was sent out in newParameters the previous time. They do resolve to the correct intent based on the context. What am I doing wrong?

Do I need to fiddle with Dialogflow's UI at all to send context params?

An example interaction based on real logs (irrelevant params removed):

/* 
  First pass:
  User msg doesn't contain any of params `value` or `product`
*/  

// agent.parameters: 
{}
// agent.context.get('seeking-params-expense-create').parameters:
undefined
// outgoing 'seeking-params-expense-create' params (lifespan 1)
{ value: '', product: '' }

/*
  Second pass:
  So far, so good.
  Next pass, we receive `value`, but not `product`.
*/

// agent.parameters:
{ value: 50, product: '' }
// agent.context.get('seeking-params-expense-create').parameters:
{ 
  'value.original': '50',
  'product.original': '', 
   value: 50,
   product: ''  
  }
// outgoing 'seeking-params-expense-create' params (lifespan 1):
{ value: 50, product: '' }


/*     
  Third pass: 
  This time, we want to use `value` from context since we
  stored in last pass and seek `product` from user.
  User only supplies `product` this time.
*/

// agent.parameters:
{ value: '', product: 'MRT' }
// agent.context.get('seeking-params-expense-create').parameters:
{ 
  'value.original': '', 
  'product.original': '',
   product: 'MRT', 
   value: ''
}
// outgoing 'seeking-params-expense-create' params (lifespan 1):
{ value: '', product: 'MRT' }
  • Can you update your question to clarify what you mean by "the incoming context params from Dialogflow don't contain the params that were sent out"? Are you saying that on the next round, "seek-create-params-context" doesn't contain what was in `newParameters`? What does it contain? Can you give examples? – Prisoner Dec 03 '18 at 11:22
  • Indeed - on the next round, "seek-create-params-context" doesn't contain what was in `newParameters`. After doing this exercise, it's also become clear that the context params contain data similar to the agent's params. – Sarup Banskota Dec 04 '18 at 02:50
  • Could it relate to the 'lifespan' of the context? I saw the lifespan is set to 1. – Kevin Yang Jan 25 '19 at 12:41

1 Answers1

2

You don't show what your Intents are, but it looks like both the second and third passes are triggered by Intents that have both the value and product parameters.

If a parameter is specified by an Intent, it will pass something, possibly an empty string, to the webhook.

It will also set that parameter in every Context that is active at that time, and pass those Contexts to the webhook as well. Even if the Context previously had a value set for that parameter.

In order to make sure your values aren't trampled by current Intents, you should store them as parameters in the Context under parameter names that aren't used by any of your Intent parameter names.

Prisoner
  • 49,922
  • 7
  • 53
  • 105