Skip to content

Commit

Permalink
reset when new messages or errors (wit-ai#78)
Browse files Browse the repository at this point in the history
* reset when new messages or errors

* addressing feedback, fixing 'this' reference

* address feedback about interactive doc updates (wit-ai#79)

* reset when new messages or errors

* addressing feedback, fixing 'this' reference

* updating CHANGES to highlight converse update

* restoring arrow notation
  • Loading branch information
patapizza authored and blandinw committed Aug 16, 2016
1 parent e91e406 commit 77f23b3
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 18 deletions.
6 changes: 3 additions & 3 deletions CHANGES.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
## v4.1.0

- Support for different JS environments
- `converse` now takes `reset` as an optional parameter

### Breaking changes

- interactive is no longer a function on the `Wit` client. Instead, you require it from the library. `require('node-wit').interactive`
- `interactive` is no longer a function on the `Wit` client. Instead, you require it from the library: `require('node-wit').interactive`
- `runActions` now resets the last turn on new messages and errors.

## v4.0.0

Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,7 @@ client.message('what is the weather in London?', {})
### runActions

A higher-level method to the Wit converse API.
`runActions` resets the last turn on new messages and errors.

Takes the following parameters:
* `sessionId` - a unique identifier describing the user session
Expand Down Expand Up @@ -145,6 +146,7 @@ Takes the following parameters:
* `sessionId` - a unique identifier describing the user session
* `message` - the text received from the user
* `context` - the object representing the session state
* `reset` - (optional) whether to reset the last turn

Example:
```js
Expand Down
57 changes: 42 additions & 15 deletions lib/wit.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ function Wit(opts) {
accessToken, apiVersion, actions, headers, logger, witURL
} = this.config = Object.freeze(validate(opts));

this._sessions = {};

this.message = (message, context) => {
let qs = 'q=' + encodeURIComponent(message);
if (context) {
Expand All @@ -38,11 +40,14 @@ function Wit(opts) {
;
};

this.converse = (sessionId, message, context) => {
this.converse = (sessionId, message, context, reset) => {
let qs = 'session_id=' + encodeURIComponent(sessionId);
if (message) {
qs += '&q=' + encodeURIComponent(message);
}
if (reset) {
qs += '&reset=true';
}
const method = 'POST';
const fullURL = witURL + '/converse?' + qs;
const handler = makeWitResponseHandler(logger, 'converse');
Expand All @@ -57,20 +62,23 @@ function Wit(opts) {
;
};

const continueRunActions = (sessionId, message, prevContext, i) => {
const continueRunActions = (sessionId, currentRequest, message, prevContext, i) => {
return (json) => {
if (i < 0) {
logger.warn('Max steps reached, stopping.');
return prevContext;
}
if (currentRequest !== this._sessions[sessionId]) {
return prevContext;
}
if (!json.type) {
throw new Error('Couldn\'t find type in Wit response');
}

logger.debug('Context: ' + JSON.stringify(prevContext));
logger.debug('Response type: ' + json.type);

// backwards-cpmpatibility with API version 20160516
// backwards-compatibility with API version 20160516
if (json.type === 'merge') {
json.type = 'action';
json.action = 'merge';
Expand All @@ -97,36 +105,55 @@ function Wit(opts) {
text: json.msg,
quickreplies: json.quickreplies,
};
return actions.send(request, response).then((ctx) => {
return actions.send(request, response).then(ctx => {
if (ctx) {
throw new Error('Cannot update context after \'send\' action');
}
if (currentRequest !== this._sessions[sessionId]) {
return ctx;
}
return this.converse(sessionId, null, prevContext).then(
continueRunActions(sessionId, message, prevContext, i - 1)
continueRunActions(sessionId, currentRequest, message, prevContext, i - 1)
);
});
} else if (json.type === 'action') {
const action = json.action;
throwIfActionMissing(actions, action);
return actions[action](request).then((ctx) => {
throwIfActionMissing(actions, json.action);
return actions[json.action](request).then(ctx => {
const nextContext = ctx || {};
if (currentRequest !== this._sessions[sessionId]) {
return nextContext;
}
return this.converse(sessionId, null, nextContext).then(
continueRunActions(sessionId, message, nextContext, i - 1)
continueRunActions(sessionId, currentRequest, message, nextContext, i - 1)
);
});
} else {
logger.debug('unknown response type', json);
logger.debug('unknown response type ' + json.type);
throw new Error('unknown response type ' + json.type);
}
}
};
};

this.runActions = (sessionId, message, context, maxSteps) => {
this.runActions = function(sessionId, message, context, maxSteps) {
if (!actions) throwMustHaveActions();
const steps = maxSteps ? maxSteps : DEFAULT_MAX_STEPS;
return this.converse(sessionId, message, context).then(
continueRunActions(sessionId, message, context, steps)
);

// Figuring out whether we need to reset the last turn.
// Each new call increments an index for the session.
// We only care about the last call to runActions.
// All the previous ones are discarded (preemptive exit).
const currentRequest = (this._sessions[sessionId] || 0) + 1;
this._sessions[sessionId] = currentRequest;
const cleanup = ctx => {
if (currentRequest === this._sessions[sessionId]) {
delete this._sessions[sessionId];
}
return ctx;
};

return this.converse(sessionId, message, context, currentRequest > 1).then(
continueRunActions(sessionId, currentRequest, message, context, steps)
).then(cleanup);
};
};

Expand Down

0 comments on commit 77f23b3

Please sign in to comment.