Skip to content

Commit

Permalink
Less goldfish (#5)
Browse files Browse the repository at this point in the history
* Added long term session attributes and functions.

* Upgraded blade-ink to v0.4.3.

* Added tests for long term session attributes.

* Updated version.
  • Loading branch information
rabidgremlin committed Aug 28, 2017
1 parent 166b4be commit 6485fa7
Show file tree
Hide file tree
Showing 22 changed files with 588 additions and 14 deletions.
16 changes: 8 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -223,10 +223,10 @@ repositories {
}
dependencies {
compile 'com.rabidgremlin:mutters-ink-bot:4.0.1'
compile 'com.rabidgremlin:mutters-opennlp-intent:4.0.1'
compile 'com.rabidgremlin:mutters-opennlp-ner:4.0.1'
compile 'com.rabidgremlin:mutters-slots:4.0.1'
compile 'com.rabidgremlin:mutters-ink-bot:4.1.0'
compile 'com.rabidgremlin:mutters-opennlp-intent:4.1.0'
compile 'com.rabidgremlin:mutters-opennlp-ner:4.1.0'
compile 'com.rabidgremlin:mutters-slots:4.1.0'
}
```

Expand All @@ -244,10 +244,10 @@ repositories {
}
dependencies {
compile 'com.rabidgremlin:mutters-ink-bot:4.0.1-SNAPSHOT'
compile 'com.rabidgremlin:mutters-opennlp-intent:4.0.1-SNAPSHOT'
compile 'com.rabidgremlin:mutters-opennlp-ner:4.0.1-SNAPSHOT'
compile 'com.rabidgremlin:mutters-slots:4.0.1-SNAPSHOT'
compile 'com.rabidgremlin:mutters-ink-bot:4.1.0-SNAPSHOT'
compile 'com.rabidgremlin:mutters-opennlp-intent:4.1.0-SNAPSHOT'
compile 'com.rabidgremlin:mutters-opennlp-ner:4.1.0-SNAPSHOT'
compile 'com.rabidgremlin:mutters-slots:4.1.0-SNAPSHOT'
}
```

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
version=4.0.1
version=4.1.0

# These are place holder values. Real values should be set in user's home gradle.properties
# and are only needed when signing and uploading to central maven repo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,12 @@
import java.util.HashMap;

/**
* This class represents a user's session with the bot. It maintains the any state needed by the bot.
* This class represents a user's session with the bot. It maintains the any state needed by the bot. The session holds
* two types of attributes. Normal attributes are typically stored whilst a conversation takes place. They are removed
* from the session when the reset() method is called which normally takes place when a conversation ends.
*
* Long term attributes are designed to hang around as long as the session. They are typically used to store data across
* conversations in the same session.
*
* @author rabidgremlin
*
Expand All @@ -15,6 +20,8 @@ public class Session
/** Map of attributes for the session. */
private HashMap<String, Object> attributes = new HashMap<String, Object>();

private HashMap<String, Object> longTermAttributes = new HashMap<String, Object>();

/**
* Get the specified attribute.
*
Expand Down Expand Up @@ -48,14 +55,56 @@ public void removeAttribute(String attributeName)
}

/**
* Resets the session. Removing all attributes.
* Resets the session. Removing all attributes. Note: Long term attributes are not removed from the session.
*
*/
public void reset()
{
attributes = new HashMap<String, Object>();
}

/**
* Get the specified long term attribute.
*
* @param attributeName The name of the attribute.
* @return The attribute or null if it isn't in the map.
*/
public Object getLongTermAttribute(String attributeName)
{
return longTermAttributes.get(attributeName.toLowerCase());
}

/**
* Sets the value of the specified long term attribute.
*
* @param attributeName The name of the attribute.
* @param value The value of the attribute.
*/
public void setLongTermAttribute(String attributeName, Object value)
{
longTermAttributes.put(attributeName.toLowerCase(), value);
}

/**
* Removes the specified long term attribute from the session.
*
* @param attributeName The name of the attribute.
*/
public void removeLongTermAttribute(String attributeName)
{
longTermAttributes.remove(attributeName.toLowerCase());
}

/**
* Resets the session. Removing all attributes (both normal and long term).
*
*/
public void resetAll()
{
attributes = new HashMap<String, Object>();
longTermAttributes = new HashMap<String, Object>();
}

/*
* (non-Javadoc)
*
Expand All @@ -65,7 +114,7 @@ public void reset()
@Override
public String toString()
{
return "Session [attributes=" + attributes + "]";
return "Session [attributes=" + attributes + ", longTermAttributes=" + longTermAttributes + "]";
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
package com.rabidgremlin.mutters.core.session;

import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.notNullValue;
import static org.hamcrest.CoreMatchers.nullValue;
import static org.junit.Assert.assertThat;

import org.junit.Test;


public class TestSession
{
@Test
public void testAttributeLifeCycle()
{
Session session = new Session();

session.setAttribute("bob", "alice");
assertThat(session.getAttribute("bob"), is("alice"));

session.removeAttribute("bob");
assertThat(session.getAttribute("bob"), is(nullValue()));
}

@Test
public void testLongTermAttributeLifeCycle()
{
Session session = new Session();

session.setLongTermAttribute("bobLT", "aliceLT");
assertThat(session.getLongTermAttribute("bobLT"), is("aliceLT"));

session.removeLongTermAttribute("bobLT");
assertThat(session.getLongTermAttribute("bobLT"), is(nullValue()));
}

@Test
public void testReset()
{
Session session = new Session();

session.setAttribute("bob", "alice");
session.setLongTermAttribute("bobLT", "aliceLT");

session.reset();

assertThat(session.getLongTermAttribute("bob"), is(nullValue()));
assertThat(session.getLongTermAttribute("bobLT"), is("aliceLT"));
}

@Test
public void testResetAll()
{
Session session = new Session();

session.setAttribute("bob", "alice");
session.setLongTermAttribute("bobLT", "aliceLT");

session.resetAll();

assertThat(session.getLongTermAttribute("bob"), is(nullValue()));
assertThat(session.getLongTermAttribute("bobLT"), is(nullValue()));
}
}
2 changes: 1 addition & 1 deletion mutters-ink-bot/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ repositories {
dependencies {
compile project(':mutters-core')

compile 'com.bladecoder.ink:blade-ink:0.4.2'
compile 'com.bladecoder.ink:blade-ink:0.4.3'
compile 'commons-io:commons-io:2.5'
compile 'org.slf4j:slf4j-api:1.7.21'
compile 'org.apache.commons:commons-lang3:3.4'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,10 @@
import com.rabidgremlin.mutters.bot.ink.InkBotConfiguration.GlobalIntent;
import com.rabidgremlin.mutters.bot.ink.functions.AddAttachmentFunction;
import com.rabidgremlin.mutters.bot.ink.functions.AddQuickReplyFunction;
import com.rabidgremlin.mutters.bot.ink.functions.GetLongTermAttributeFunction;
import com.rabidgremlin.mutters.bot.ink.functions.RemoveLongTermAttributeFunction;
import com.rabidgremlin.mutters.bot.ink.functions.SetHintFunction;
import com.rabidgremlin.mutters.bot.ink.functions.SetLongTermAttributeFunction;
import com.rabidgremlin.mutters.bot.ink.functions.SetRepromptFunction;
import com.rabidgremlin.mutters.core.Context;
import com.rabidgremlin.mutters.core.IntentMatch;
Expand Down Expand Up @@ -99,6 +102,9 @@ public InkBot(T configuration)
addFunction(new SetRepromptFunction());
addFunction(new AddAttachmentFunction());
addFunction(new AddQuickReplyFunction());
addFunction(new SetLongTermAttributeFunction());
addFunction(new GetLongTermAttributeFunction());
addFunction(new RemoveLongTermAttributeFunction());

// add any other functions for the bot
List<InkBotFunction> functions = configuration.getInkFunctions();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
package com.rabidgremlin.mutters.bot.ink.functions;

import com.bladecoder.ink.runtime.Story;
import com.rabidgremlin.mutters.bot.ink.CurrentResponse;
import com.rabidgremlin.mutters.bot.ink.InkBotFunction;
import com.rabidgremlin.mutters.core.IntentMatch;
import com.rabidgremlin.mutters.core.session.Session;

/**
* This function gets the value of a long term session attribute. These attributes are not removed at the end of a
* conversation so they can be used to share context between conversations in the same session.
*
* For example in your Ink script you could have:
* ```
* VAR current_order = ""
*
* === check_order_status ===
* ::GET_LONG_TERM_ATTR name::currentorder var::current_order
* {
* - current_order == "":
* -> get_order_number_for_status_check // this would prompt for order number and store in current_order then jump to check_order_status
* - else:
* -> check_order_status // retrieves and displays status for order number in current_order
* }
* -> END
* ```
*
* Note: If there is no long term attribute with the specified name in the session then the specified Ink variable
* will be set to "".
*
*
* @author rabidgremlin
*
*/
public class GetLongTermAttributeFunction
implements InkBotFunction
{

/*
* (non-Javadoc)
*
* @see com.rabidgremlin.mutters.bot.ink.InkBotFunction#getFunctionName()
*/
@Override
public String getFunctionName()
{
return "GET_LONG_TERM_ATTR";
}

/*
* (non-Javadoc)
*
* @see com.rabidgremlin.mutters.bot.ink.InkBotFunction#respondexecute(CurrentResponse currentResponse, Session
* session, IntentMatch intentMatch, Story story, String param)
*/
@Override
public void execute(CurrentResponse currentResponse, Session session, IntentMatch intentMatch, Story story, String param)
{
FunctionDetails details = FunctionHelper.parseFunctionString(param);

if (details.getFunctionParams() == null)
{
throw new IllegalArgumentException("Missing name and variable value for GET_LONG_TERM_ATTR");
}

String name = details.getFunctionParams().get("name");
if (name == null)
{
throw new IllegalArgumentException("Missing name value for GET_LONG_TERM_ATTR");
}

String var = details.getFunctionParams().get("var");
if (var == null)
{
throw new IllegalArgumentException("Missing var value for GET_LONG_TERM_ATTR");
}

try
{
Object value = session.getLongTermAttribute(name);
if (value == null)
{
story.getVariablesState().set(var, "");
}
else
{
story.getVariablesState().set(var, value);
}
}
catch(Exception e)
{
throw new RuntimeException("Failed to get long term attribute",e);
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
package com.rabidgremlin.mutters.bot.ink.functions;

import com.bladecoder.ink.runtime.Story;
import com.rabidgremlin.mutters.bot.ink.CurrentResponse;
import com.rabidgremlin.mutters.bot.ink.InkBotFunction;
import com.rabidgremlin.mutters.core.IntentMatch;
import com.rabidgremlin.mutters.core.session.Session;

/**
* This function removes the specified long term session attribute from the session.
* These attributes are not removed at the end of a conversation so they can be used
* to share context between conversations in the same session.
*
* For example in your Ink script you could have:
* ```
* VAR current_order = ""
*
* === check_order_status ===
* ::GET_LONG_TERM_ATTR name::currentorder var::current_order
* For order {current_order} ?
* + YesIntent
* -> display_order_details
* + NoIntent
* ::REMOVE_LONG_TERM_ATTR name::currentorder
* -> get_order_number
* -> END
* ```
*
*
* @author rabidgremlin
*
*/
public class RemoveLongTermAttributeFunction
implements InkBotFunction
{

/*
* (non-Javadoc)
*
* @see com.rabidgremlin.mutters.bot.ink.InkBotFunction#getFunctionName()
*/
@Override
public String getFunctionName()
{
return "REMOVE_LONG_TERM_ATTR";
}

/*
* (non-Javadoc)
*
* @see com.rabidgremlin.mutters.bot.ink.InkBotFunction#respondexecute(CurrentResponse currentResponse, Session
* session, IntentMatch intentMatch, Story story, String param)
*/
@Override
public void execute(CurrentResponse currentResponse, Session session, IntentMatch intentMatch, Story story, String param)
{
FunctionDetails details = FunctionHelper.parseFunctionString(param);

if (details.getFunctionParams() == null)
{
throw new IllegalArgumentException("Missing name and value values for REMOVE_LONG_TERM_ATTR");
}

String name = details.getFunctionParams().get("name");
if (name == null)
{
throw new IllegalArgumentException("Missing name value for REMOVE_LONG_TERM_ATTR");
}

session.removeLongTermAttribute(name);
}

}
Loading

0 comments on commit 6485fa7

Please sign in to comment.