wit 5.0.0 → 6.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGES.md +8 -0
- data/README.md +1 -42
- data/examples/basic.rb +1 -7
- data/examples/celebrities.rb +48 -0
- data/examples/joke.rb +22 -27
- data/examples/wit-example-celebrities.zip +0 -0
- data/examples/wit-example-joke-bot.zip +0 -0
- data/lib/wit.rb +9 -144
- data/wit.gemspec +1 -1
- metadata +9 -7
- data/examples/quickstart.rb +0 -43
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: db82d7c5e9dad4d0566d3bd8bb047954bec32e8b
|
4
|
+
data.tar.gz: 40cbef76d441b36725adfbfe30b31c3271b231aa
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 2eafba1307cd42ecdf78358e64caf018b90fe7065c90e61f38758b3e6abfd56a0d668a193ed54f4b87648c6435df0c9c6f9dc22de4064037266b3dbba7eb0ac2
|
7
|
+
data.tar.gz: 2cfdfddd281f45dd45f32eddd37df3dfcc2bad3064ee3acdf0e4109ddbb793a4bdd6617dc892280de1207640496c00fcdd64c097dfbf43d5d5cb4c133fb097d1
|
data/CHANGES.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
## v6.0.0
|
2
|
+
The most important change is the removal of `.converse()` and `.run_actions()`. Follow the migration tutorial [here](https://github.com/wit-ai/wit-stories-migration-tutorial), or [read more here](https://wit.ai/blog/2017/07/27/sunsetting-stories).
|
3
|
+
|
4
|
+
### Breaking changes
|
5
|
+
|
6
|
+
- `converse` and `run_actions` are removed
|
7
|
+
- updated and added new examples that leverage the /message API
|
8
|
+
|
1
9
|
## v5.0.0
|
2
10
|
|
3
11
|
- `converse` and `run_actions` are deprecated
|
data/README.md
CHANGED
@@ -21,7 +21,7 @@ gem install wit-*.gem
|
|
21
21
|
Run in your terminal:
|
22
22
|
|
23
23
|
```bash
|
24
|
-
ruby examples/
|
24
|
+
ruby examples/basic.rb <your_token>
|
25
25
|
```
|
26
26
|
|
27
27
|
See the `examples` folder for more examples.
|
@@ -69,47 +69,6 @@ Example:
|
|
69
69
|
client.interactive
|
70
70
|
```
|
71
71
|
|
72
|
-
### .run_actions()
|
73
|
-
|
74
|
-
**DEPRECATED** See [our blog post](https://wit.ai/blog) for a migration plan.
|
75
|
-
|
76
|
-
A higher-level method to the Wit converse API.
|
77
|
-
`run_actions` resets the last turn on new messages and errors.
|
78
|
-
|
79
|
-
Takes the following parameters:
|
80
|
-
* `session_id` - a unique identifier describing the user session
|
81
|
-
* `message` - the text received from the user
|
82
|
-
* `context` - the `Hash` representing the session state
|
83
|
-
* `max_steps` - (optional) the maximum number of actions to execute (defaults to 5)
|
84
|
-
|
85
|
-
Example:
|
86
|
-
```ruby
|
87
|
-
session = 'my-user-session-42'
|
88
|
-
context0 = {}
|
89
|
-
context1 = client.run_actions(session, 'what is the weather in London?', context0)
|
90
|
-
p "The session state is now: #{context1}"
|
91
|
-
context2 = client.run_actions(session, 'and in Brussels?', context1)
|
92
|
-
p "The session state is now: #{context2}"
|
93
|
-
```
|
94
|
-
|
95
|
-
### .converse()
|
96
|
-
|
97
|
-
**DEPRECATED** See [our blog post](https://wit.ai/blog) for a migration plan.
|
98
|
-
|
99
|
-
The low-level Wit [converse API](https://wit.ai/docs/http/20160330#converse-link).
|
100
|
-
|
101
|
-
Takes the following parameters:
|
102
|
-
* `session_id` - a unique identifier describing the user session
|
103
|
-
* `msg` - the text received from the user
|
104
|
-
* `context` - the `Hash` representing the session state
|
105
|
-
* `reset` - (optional) whether to reset the last turn
|
106
|
-
|
107
|
-
Example:
|
108
|
-
```ruby
|
109
|
-
rsp = client.converse('my-user-session-42', 'what is the weather in London?', {})
|
110
|
-
puts("Yay, got Wit.ai response: #{rsp}")
|
111
|
-
```
|
112
|
-
|
113
72
|
### CRUD operations for entities
|
114
73
|
payload in the parameters is a hash containing API arguments
|
115
74
|
|
data/examples/basic.rb
CHANGED
@@ -8,11 +8,5 @@ end
|
|
8
8
|
access_token = ARGV[0]
|
9
9
|
ARGV.shift
|
10
10
|
|
11
|
-
|
12
|
-
send: -> (request, response) {
|
13
|
-
puts("sending... #{response['text']}")
|
14
|
-
},
|
15
|
-
}
|
16
|
-
|
17
|
-
client = Wit.new(access_token: access_token, actions: actions)
|
11
|
+
client = Wit.new(access_token: access_token)
|
18
12
|
client.interactive
|
@@ -0,0 +1,48 @@
|
|
1
|
+
require 'wit'
|
2
|
+
|
3
|
+
if ARGV.length == 0
|
4
|
+
puts("usage: #{$0} <wit-access-token>")
|
5
|
+
exit 1
|
6
|
+
end
|
7
|
+
|
8
|
+
access_token = ARGV[0]
|
9
|
+
ARGV.shift
|
10
|
+
|
11
|
+
# Celebrities example
|
12
|
+
# See https://wit.ai/aforaleka/wit-example-celebrities/
|
13
|
+
|
14
|
+
def first_entity_value(entities, entity)
|
15
|
+
return nil unless entities.has_key? entity
|
16
|
+
val = entities[entity][0]['value']
|
17
|
+
return nil if val.nil?
|
18
|
+
return val
|
19
|
+
end
|
20
|
+
|
21
|
+
def handle_message(response)
|
22
|
+
entities = response['entities']
|
23
|
+
greetings = first_entity_value(entities, 'greetings')
|
24
|
+
celebrity = first_entity_value(entities, 'notable_person')
|
25
|
+
|
26
|
+
case
|
27
|
+
when celebrity
|
28
|
+
return wikidata_description(celebrity)
|
29
|
+
when greetings
|
30
|
+
return "Hi! You can say something like 'Tell me about Beyonce'"
|
31
|
+
else
|
32
|
+
return "Um. I don't recognize that name. " \
|
33
|
+
"Which celebrity do you want to learn about?"
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def wikidata_description(celebrity)
|
38
|
+
return "I recognize #{celebrity['name']}" unless celebrity.dig('external', 'wikidata')
|
39
|
+
wikidata_id = celebrity.fetch('external').fetch('wikidata')
|
40
|
+
api = URI("https://www.wikidata.org/w/api.php?action=wbgetentities&format=json&ids=#{wikidata_id}&props=descriptions&languages=en")
|
41
|
+
rsp = Net::HTTP.get_response(api)
|
42
|
+
wikidata = JSON.parse(rsp.body)
|
43
|
+
description = wikidata['entities'][wikidata_id]['descriptions']['en']['value']
|
44
|
+
return "ooo yes I know #{celebrity['name']} -- #{description}"
|
45
|
+
end
|
46
|
+
|
47
|
+
client = Wit.new(access_token: access_token)
|
48
|
+
client.interactive(method(:handle_message))
|
data/examples/joke.rb
CHANGED
@@ -9,7 +9,7 @@ access_token = ARGV[0]
|
|
9
9
|
ARGV.shift
|
10
10
|
|
11
11
|
# Joke example
|
12
|
-
# See https://wit.ai/
|
12
|
+
# See https://wit.ai/aforaleka/wit-example-joke-bot/
|
13
13
|
|
14
14
|
def first_entity_value(entities, entity)
|
15
15
|
return nil unless entities.has_key? entity
|
@@ -18,7 +18,7 @@ def first_entity_value(entities, entity)
|
|
18
18
|
return val.is_a?(Hash) ? val['value'] : val
|
19
19
|
end
|
20
20
|
|
21
|
-
all_jokes = {
|
21
|
+
$all_jokes = {
|
22
22
|
'chuck' => [
|
23
23
|
'Chuck Norris counted to infinity - twice.',
|
24
24
|
'Death once had a near-Chuck Norris experience.',
|
@@ -32,29 +32,24 @@ all_jokes = {
|
|
32
32
|
],
|
33
33
|
}
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
context['joke'] = all_jokes[context['category'] || 'default'].sample
|
55
|
-
return context
|
56
|
-
},
|
57
|
-
}
|
35
|
+
def handle_message(response)
|
36
|
+
entities = response['entities']
|
37
|
+
get_joke = first_entity_value(entities, 'getJoke')
|
38
|
+
greetings = first_entity_value(entities, 'greetings')
|
39
|
+
category = first_entity_value(entities, 'category')
|
40
|
+
sentiment = first_entity_value(entities, 'sentiment')
|
41
|
+
|
42
|
+
case
|
43
|
+
when get_joke
|
44
|
+
return $all_jokes[category || 'default'].sample
|
45
|
+
when sentiment
|
46
|
+
return sentiment == 'positive' ? 'Glad you liked it.' : 'Hmm.'
|
47
|
+
when greetings
|
48
|
+
return 'Hey this is joke bot :)'
|
49
|
+
else
|
50
|
+
return 'I can tell jokes! Say "tell me a joke about tech"!'
|
51
|
+
end
|
52
|
+
end
|
58
53
|
|
59
|
-
client = Wit.new(access_token: access_token
|
60
|
-
client.interactive
|
54
|
+
client = Wit.new(access_token: access_token)
|
55
|
+
client.interactive(method(:handle_message))
|
Binary file
|
Binary file
|
data/lib/wit.rb
CHANGED
@@ -17,13 +17,6 @@ class Wit
|
|
17
17
|
if opts[:logger]
|
18
18
|
@logger = opts[:logger]
|
19
19
|
end
|
20
|
-
|
21
|
-
if opts[:actions]
|
22
|
-
logger.warn('Stories and POST /converse have been deprecated. This will break in February 2018!')
|
23
|
-
@actions = validate_actions(logger, opts[:actions])
|
24
|
-
end
|
25
|
-
|
26
|
-
@_sessions = {}
|
27
20
|
end
|
28
21
|
|
29
22
|
def logger
|
@@ -34,54 +27,16 @@ class Wit
|
|
34
27
|
end
|
35
28
|
end
|
36
29
|
|
37
|
-
def message(msg)
|
30
|
+
def message(msg, n=nil, verbose=nil)
|
38
31
|
params = {}
|
39
32
|
params[:q] = msg unless msg.nil?
|
33
|
+
params[:n] = n unless n.nil?
|
34
|
+
params[:verbose] = verbose unless verbose.nil?
|
40
35
|
res = req(logger, @access_token, Net::HTTP::Get, '/message', params)
|
41
36
|
return res
|
42
37
|
end
|
43
38
|
|
44
|
-
def
|
45
|
-
if !context.is_a?(Hash)
|
46
|
-
raise Error.new('context should be a Hash')
|
47
|
-
end
|
48
|
-
params = {}
|
49
|
-
params[:q] = msg unless msg.nil?
|
50
|
-
params[:session_id] = session_id
|
51
|
-
params[:reset] = true if reset
|
52
|
-
res = req(logger, @access_token, Net::HTTP::Post, '/converse', params, context)
|
53
|
-
return res
|
54
|
-
end
|
55
|
-
|
56
|
-
def run_actions(session_id, message, context={}, max_steps=DEFAULT_MAX_STEPS)
|
57
|
-
if !@actions
|
58
|
-
throw_must_have_actions
|
59
|
-
end
|
60
|
-
if !context.is_a?(Hash)
|
61
|
-
raise Error.new('context should be a Hash')
|
62
|
-
end
|
63
|
-
|
64
|
-
# Figuring out whether we need to reset the last turn.
|
65
|
-
# Each new call increments an index for the session.
|
66
|
-
# We only care about the last call to run_actions.
|
67
|
-
# All the previous ones are discarded (preemptive exit).
|
68
|
-
current_request = 1
|
69
|
-
if @_sessions.has_key?(session_id)
|
70
|
-
current_request = @_sessions[session_id] + 1
|
71
|
-
end
|
72
|
-
@_sessions[session_id] = current_request
|
73
|
-
|
74
|
-
context = __run_actions(session_id, current_request, message, context, max_steps)
|
75
|
-
|
76
|
-
# Cleaning up once the last call to run_actions finishes.
|
77
|
-
if current_request == @_sessions[session_id]
|
78
|
-
@_sessions.delete(session_id)
|
79
|
-
end
|
80
|
-
|
81
|
-
return context
|
82
|
-
end
|
83
|
-
|
84
|
-
def interactive(context={})
|
39
|
+
def interactive(handle_message=nil, context={})
|
85
40
|
while true
|
86
41
|
print '> '
|
87
42
|
msg = STDIN.gets.strip
|
@@ -90,7 +45,11 @@ class Wit
|
|
90
45
|
end
|
91
46
|
|
92
47
|
begin
|
93
|
-
|
48
|
+
if handle_message.nil?
|
49
|
+
puts(message(msg))
|
50
|
+
else
|
51
|
+
puts(handle_message.call(message(msg)))
|
52
|
+
end
|
94
53
|
rescue Error => exp
|
95
54
|
logger.error("error: #{exp.message}")
|
96
55
|
end
|
@@ -99,16 +58,6 @@ class Wit
|
|
99
58
|
puts
|
100
59
|
end
|
101
60
|
|
102
|
-
def throw_if_action_missing(action_name)
|
103
|
-
if !@actions.has_key?(action_name)
|
104
|
-
raise Error.new("unknown action: #{action_name}")
|
105
|
-
end
|
106
|
-
end
|
107
|
-
|
108
|
-
def throw_must_have_actions()
|
109
|
-
raise Error.new('You must provide the `actions` parameter to be able to use runActions. ' + LEARN_MORE)
|
110
|
-
end
|
111
|
-
|
112
61
|
def get_entities
|
113
62
|
req(logger, @access_token, Net::HTTP::Get, "/entities")
|
114
63
|
end
|
@@ -171,67 +120,6 @@ class Wit
|
|
171
120
|
end
|
172
121
|
end
|
173
122
|
|
174
|
-
def __run_actions(session_id, current_request, message, context, i)
|
175
|
-
if i <= 0
|
176
|
-
raise Error.new('Max steps reached, stopping.')
|
177
|
-
end
|
178
|
-
json = converse(session_id, message, context)
|
179
|
-
if json['type'].nil?
|
180
|
-
raise Error.new('Couldn\'t find type in Wit response')
|
181
|
-
end
|
182
|
-
if current_request != @_sessions[session_id]
|
183
|
-
return context
|
184
|
-
end
|
185
|
-
|
186
|
-
logger.debug("Context: #{context}")
|
187
|
-
logger.debug("Response type: #{json['type']}")
|
188
|
-
|
189
|
-
# backwards-compatibility with API version 20160516
|
190
|
-
if json['type'] == 'merge'
|
191
|
-
json['type'] = 'action'
|
192
|
-
json['action'] = 'merge'
|
193
|
-
end
|
194
|
-
|
195
|
-
if json['type'] == 'error'
|
196
|
-
raise Error.new('Oops, I don\'t know what to do.')
|
197
|
-
end
|
198
|
-
|
199
|
-
if json['type'] == 'stop'
|
200
|
-
return context
|
201
|
-
end
|
202
|
-
|
203
|
-
request = {
|
204
|
-
'session_id' => session_id,
|
205
|
-
'context' => context.clone,
|
206
|
-
'text' => message,
|
207
|
-
'entities' => json['entities']
|
208
|
-
}
|
209
|
-
if json['type'] == 'msg'
|
210
|
-
throw_if_action_missing(:send)
|
211
|
-
response = {
|
212
|
-
'text' => json['msg'],
|
213
|
-
'quickreplies' => json['quickreplies'],
|
214
|
-
}
|
215
|
-
@actions[:send].call(request, response)
|
216
|
-
elsif json['type'] == 'action'
|
217
|
-
action = json['action'].to_sym
|
218
|
-
throw_if_action_missing(action)
|
219
|
-
context = @actions[action].call(request)
|
220
|
-
if context.nil?
|
221
|
-
logger.warn('missing context - did you forget to return it?')
|
222
|
-
context = {}
|
223
|
-
end
|
224
|
-
else
|
225
|
-
raise Error.new("unknown type: #{json['type']}")
|
226
|
-
end
|
227
|
-
|
228
|
-
if current_request != @_sessions[session_id]
|
229
|
-
return context
|
230
|
-
end
|
231
|
-
|
232
|
-
return __run_actions(session_id, current_request, nil, context, i - 1)
|
233
|
-
end
|
234
|
-
|
235
123
|
def req(logger, access_token, meth_class, path, params={}, payload={})
|
236
124
|
uri = URI(WIT_API_HOST + path)
|
237
125
|
uri.query = URI.encode_www_form(params)
|
@@ -257,27 +145,4 @@ class Wit
|
|
257
145
|
json
|
258
146
|
end
|
259
147
|
end
|
260
|
-
|
261
|
-
def validate_actions(logger, actions)
|
262
|
-
[:send].each do |action|
|
263
|
-
if !actions.has_key?(action)
|
264
|
-
logger.warn "The #{action} action is missing. #{LEARN_MORE}"
|
265
|
-
end
|
266
|
-
end
|
267
|
-
actions.each_pair do |k, v|
|
268
|
-
if !k.is_a?(Symbol)
|
269
|
-
logger.warn "The '#{k}' action name should be a symbol"
|
270
|
-
end
|
271
|
-
if !(v.respond_to?(:call) && v.lambda?)
|
272
|
-
logger.warn "The '#{k}' action should be a lambda function"
|
273
|
-
end
|
274
|
-
if k == :send && v.arity != 2
|
275
|
-
logger.warn "The \'send\' action should take 2 arguments: request and response. #{LEARN_MORE}"
|
276
|
-
end
|
277
|
-
if k != :send && v.arity != 1
|
278
|
-
logger.warn "The '#{k}' action should take 1 argument: request. #{LEARN_MORE}"
|
279
|
-
end
|
280
|
-
end
|
281
|
-
return actions
|
282
|
-
end
|
283
148
|
end
|
data/wit.gemspec
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: wit
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 6.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- The Wit Team
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2018-02-08 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: Ruby SDK for Wit.ai
|
14
14
|
email: help@wit.ai
|
@@ -16,14 +16,16 @@ executables: []
|
|
16
16
|
extensions: []
|
17
17
|
extra_rdoc_files: []
|
18
18
|
files:
|
19
|
-
- .gitignore
|
19
|
+
- ".gitignore"
|
20
20
|
- CHANGES.md
|
21
21
|
- Gemfile
|
22
22
|
- LICENSE
|
23
23
|
- README.md
|
24
24
|
- examples/basic.rb
|
25
|
+
- examples/celebrities.rb
|
25
26
|
- examples/joke.rb
|
26
|
-
- examples/
|
27
|
+
- examples/wit-example-celebrities.zip
|
28
|
+
- examples/wit-example-joke-bot.zip
|
27
29
|
- lib/wit.rb
|
28
30
|
- wit.gemspec
|
29
31
|
homepage: https://wit.ai
|
@@ -36,17 +38,17 @@ require_paths:
|
|
36
38
|
- lib
|
37
39
|
required_ruby_version: !ruby/object:Gem::Requirement
|
38
40
|
requirements:
|
39
|
-
- -
|
41
|
+
- - ">="
|
40
42
|
- !ruby/object:Gem::Version
|
41
43
|
version: 1.9.3
|
42
44
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
43
45
|
requirements:
|
44
|
-
- -
|
46
|
+
- - ">="
|
45
47
|
- !ruby/object:Gem::Version
|
46
48
|
version: '0'
|
47
49
|
requirements: []
|
48
50
|
rubyforge_project:
|
49
|
-
rubygems_version: 2.
|
51
|
+
rubygems_version: 2.5.2
|
50
52
|
signing_key:
|
51
53
|
specification_version: 4
|
52
54
|
summary: Ruby SDK for Wit.ai
|
data/examples/quickstart.rb
DELETED
@@ -1,43 +0,0 @@
|
|
1
|
-
require 'wit'
|
2
|
-
|
3
|
-
if ARGV.length == 0
|
4
|
-
puts("usage: #{$0} <wit-access-token>")
|
5
|
-
exit 1
|
6
|
-
end
|
7
|
-
|
8
|
-
access_token = ARGV[0]
|
9
|
-
ARGV.shift
|
10
|
-
|
11
|
-
# Quickstart example
|
12
|
-
# See https://wit.ai/ar7hur/Quickstart
|
13
|
-
|
14
|
-
def first_entity_value(entities, entity)
|
15
|
-
return nil unless entities.has_key? entity
|
16
|
-
val = entities[entity][0]['value']
|
17
|
-
return nil if val.nil?
|
18
|
-
return val.is_a?(Hash) ? val['value'] : val
|
19
|
-
end
|
20
|
-
|
21
|
-
actions = {
|
22
|
-
send: -> (request, response) {
|
23
|
-
puts("sending... #{response['text']}")
|
24
|
-
},
|
25
|
-
getForecast: -> (request) {
|
26
|
-
context = request['context']
|
27
|
-
entities = request['entities']
|
28
|
-
|
29
|
-
loc = first_entity_value(entities, 'location')
|
30
|
-
if loc
|
31
|
-
context['forecast'] = 'sunny'
|
32
|
-
context.delete('missingLocation')
|
33
|
-
else
|
34
|
-
context['missingLocation'] = true
|
35
|
-
context.delete('forecast')
|
36
|
-
end
|
37
|
-
|
38
|
-
return context
|
39
|
-
},
|
40
|
-
}
|
41
|
-
|
42
|
-
client = Wit.new(access_token: access_token, actions: actions)
|
43
|
-
client.interactive
|