wit 5.0.0 → 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|