wit 2.0.0 → 3.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fb6fd4fd673c2e0a4788d1f843d316fa925a7afd
4
- data.tar.gz: f86c64544a7dd61b3b1f232c3a9a9e48e590d38b
3
+ metadata.gz: 20bcf5fae1df0ea0fe610b69f059f21dbe12f5e1
4
+ data.tar.gz: 9784d136f7e6dcd658dd5f902ac882a38f294b2b
5
5
  SHA512:
6
- metadata.gz: f4de22f57f076e5946c600e45a2cd09e8fbe222bbe5ff6215bcdd7bb978e51a6224ca5f74bfe5a7013c37085d093c1b393aa8d34305c7635b55753ba2f6fd41c
7
- data.tar.gz: aa5003e437f4716b8961d0d58f42449a3ce490bc09b7c891a144e1bd605bf55e206162f111422221b786533a97651a1d756100ea7a5325b0b6ad1d413f43ec06
6
+ metadata.gz: bcc746f4aa7fe8e71ec4e5f0c4aff56b6c61b968f0bff398a3de3280e7698b50073ce4f0c9e953e485f96c983809373015e88027272cfe75160af3fb9a760e29
7
+ data.tar.gz: 6ec24766a8061ab26d2530c1631f84c30d352ee87c7ca51fb70eeb8ec0a06714657570a9c925d4a87b6baa5c58b27a0ccd7bd6e8a19a0877951991685a5d4af0
data/CHANGES.md CHANGED
@@ -1,3 +1,11 @@
1
+ ## v3.0
2
+
3
+ Bot Engine integration
4
+
5
+ ### breaking
6
+
7
+ - the `message` API is wrapped around a `Wit` class, and doesn't take the token as first parameter
8
+
1
9
  ## v2.0
2
10
 
3
11
  Rewrite in pure Ruby
data/README.md CHANGED
@@ -1,40 +1,33 @@
1
1
  # wit-ruby
2
2
 
3
- `wit-ruby` is a Ruby client to easily use the [Wit.ai](http://wit.ai) HTTP API.
3
+ `wit-ruby` is the Ruby SDK for [Wit.ai](http://wit.ai).
4
4
 
5
5
  ## Install
6
6
 
7
+ From RubyGems:
7
8
  ```bash
8
9
  gem install wit
9
10
  ```
10
11
 
11
- ## Usage
12
-
13
- ```ruby
14
- require 'wit'
15
- p Wit.message('MY_ACCESS_TOKEN', 'turn on the lights in the kitchen')
16
- ```
17
-
18
- See below for more examples.
19
-
20
- ## Install from source
21
-
12
+ From source:
22
13
  ```bash
23
14
  git clone https://github.com/wit-ai/wit-ruby
24
15
  gem build wit.gemspec
25
16
  gem install wit-*.gem
26
17
  ```
27
18
 
28
- ## API
19
+ ## Usage
29
20
 
30
- ```ruby
31
- require 'wit'
21
+ See the `examples` folder for examples.
32
22
 
33
- access_token = 'MY_ACCESS_TOKEN'
23
+ ## API
34
24
 
35
- # GET /message to extract intent and entities from user request
36
- p Wit.message(access_token, 'turn on the lights in the kitchen')
37
- ```
25
+ `wit-ruby` provides a Wit class with the following methods:
26
+ * `message` - the Wit message API
27
+ * `converse` - the low-level Wit converse API
28
+ * `run_actions` - a higher-level method to the Wit converse API
29
+
30
+ See the [docs](https://wit.ai/docs) for more information.
38
31
 
39
32
  ## Thanks
40
33
 
data/examples/joke.rb ADDED
@@ -0,0 +1,55 @@
1
+ require 'wit'
2
+
3
+ # Joke example
4
+ # See https://wit.ai/patapizza/example-joke
5
+
6
+ access_token = 'YOUR_ACCESS_TOKEN'
7
+
8
+ def first_entity_value(entities, entity)
9
+ return nil unless entities.has_key? entity
10
+ val = entities[entity][0]['value']
11
+ return nil if val.nil?
12
+ return val.is_a?(Hash) ? val['value'] : val
13
+ end
14
+
15
+ all_jokes = {
16
+ 'chuck' => [
17
+ 'Chuck Norris counted to infinity - twice.',
18
+ 'Death once had a near-Chuck Norris experience.',
19
+ ],
20
+ 'tech' => [
21
+ 'Did you hear about the two antennas that got married? The ceremony was long and boring, but the reception was great!',
22
+ 'Why do geeks mistake Halloween and Christmas? Because Oct 31 === Dec 25.',
23
+ ],
24
+ 'default' => [
25
+ 'Why was the Math book sad? Because it had so many problems.',
26
+ ],
27
+ }
28
+
29
+ actions = {
30
+ :say => -> (session_id, msg) {
31
+ p msg
32
+ },
33
+ :merge => -> (context, entities) {
34
+ new_context = context.clone
35
+ new_context.delete 'joke'
36
+ new_context.delete 'ack'
37
+ category = first_entity_value entities, 'category'
38
+ new_context['category'] = category unless category.nil?
39
+ sentiment = first_entity_value entities, 'sentiment'
40
+ new_context['ack'] = sentiment == 'positive' ? 'Glad you liked it.' : 'Hmm.' unless sentiment.nil?
41
+ return new_context
42
+ },
43
+ :error => -> (session_id, msg) {
44
+ p 'Oops I don\'t know what to do.'
45
+ },
46
+ :'select-joke' => -> (context) {
47
+ new_context = context.clone
48
+ new_context['joke'] = all_jokes[new_context['cat'] || 'default'].sample
49
+ return new_context
50
+ },
51
+ }
52
+ client = Wit.new access_token, actions
53
+
54
+ session_id = 'my-user-id-42'
55
+ client.run_actions session_id, 'tell me a joke about tech', {}
@@ -0,0 +1,37 @@
1
+ require 'wit'
2
+
3
+ # Quickstart example
4
+ # See https://wit.ai/l5t/Quickstart
5
+
6
+ access_token = 'YOUR_ACCESS_TOKEN'
7
+
8
+ def first_entity_value(entities, entity)
9
+ return nil unless entities.has_key? entity
10
+ val = entities[entity][0]['value']
11
+ return nil if val.nil?
12
+ return val.is_a?(Hash) ? val['value'] : val
13
+ end
14
+
15
+ actions = {
16
+ :say => -> (session_id, msg) {
17
+ p msg
18
+ },
19
+ :merge => -> (context, entities) {
20
+ new_context = context.clone
21
+ loc = first_entity_value entities, 'location'
22
+ new_context['loc'] = loc unless loc.nil?
23
+ return new_context
24
+ },
25
+ :error => -> (session_id, msg) {
26
+ p 'Oops I don\'t know what to do.'
27
+ },
28
+ :'fetch-weather' => -> (context) {
29
+ new_context = context.clone
30
+ new_context['forecast'] = 'sunny'
31
+ return new_context
32
+ },
33
+ }
34
+ client = Wit.new access_token, actions
35
+
36
+ session_id = 'my-user-id-42'
37
+ client.run_actions session_id, 'weather in London', {}
@@ -0,0 +1,19 @@
1
+ require 'wit'
2
+
3
+ access_token = 'YOUR_ACCESS_TOKEN'
4
+
5
+ actions = {
6
+ :say => -> (session_id, msg) {
7
+ p msg
8
+ },
9
+ :merge => -> (context, entities) {
10
+ return context
11
+ },
12
+ :error => -> (session_id, msg) {
13
+ p 'Oops I don\'t know what to do.'
14
+ },
15
+ }
16
+ client = Wit.new access_token, actions
17
+
18
+ session_id = 'my-user-id-42'
19
+ client.run_actions session_id, 'your message', {}
data/lib/wit.rb CHANGED
@@ -1,37 +1,103 @@
1
- module Wit
2
- require 'json'
3
- require 'net/http'
1
+ require 'json'
2
+ require 'net/http'
4
3
 
5
- WIT_API_HOST = ENV['WIT_URL'] || 'https://api.wit.ai'
4
+ WIT_API_HOST = ENV['WIT_URL'] || 'https://api.wit.ai'
5
+ DEFAULT_MAX_STEPS = 5
6
6
 
7
- class WitException < Exception
8
- end
7
+ class WitException < Exception
8
+ end
9
9
 
10
- def self.req(access_token, meth_class, path, params)
11
- uri = URI(WIT_API_HOST + path)
12
- uri.query = URI.encode_www_form(params)
10
+ def req(access_token, meth_class, path, params={}, payload={})
11
+ uri = URI(WIT_API_HOST + path)
12
+ uri.query = URI.encode_www_form params
13
13
 
14
- req = meth_class.new(uri)
15
- req['authorization'] = 'Bearer ' + access_token
16
- req['accept'] = 'application/vnd.wit.20160330+json'
14
+ request = meth_class.new uri
15
+ request['authorization'] = 'Bearer ' + access_token
16
+ request['accept'] = 'application/vnd.wit.20160330+json'
17
+ request.add_field 'Content-Type', 'application/json'
18
+ request.body = payload.to_json
17
19
 
18
- Net::HTTP.start(
19
- uri.host, uri.port, :use_ssl => uri.scheme == 'https'
20
- ) do |http|
21
- rsp = http.request(req)
22
- if rsp.code.to_i > 200
23
- raise WitException.new('HTTP error code=' + rsp.code)
24
- end
20
+ Net::HTTP.start uri.host, uri.port, {:use_ssl => uri.scheme == 'https'} do |http|
21
+ rsp = http.request request
22
+ raise WitException.new "HTTP error code=#{rsp.code}" unless rsp.code.to_i <= 200
23
+ JSON.parse rsp.body
24
+ end
25
+ end
25
26
 
26
- JSON.parse(rsp.body)
27
- end
27
+ def validate_actions(actions)
28
+ learn_more = 'Learn more at https://wit.ai/docs/quickstart'
29
+ raise WitException.new 'The second parameter should be a Hash' unless actions.is_a? Hash
30
+ [:say, :merge, :error].each do |action|
31
+ raise WitException.new "The #{action} action is missing. #{learn_more}" unless actions.has_key? action
32
+ end
33
+ actions.each_pair do |k, v|
34
+ raise WitException.new "The '#{k}' action name should be a symbol" unless k.is_a? Symbol
35
+ raise WitException.new "The '#{k}' action should be a lambda function" unless v.respond_to? :call and v.lambda?
36
+ raise WitException.new "The \'say\' action should take 2 arguments: session_id, msg. #{learn_more}" if k == :say and v.arity != 2
37
+ raise WitException.new "The \'merge\' action should take 2 arguments: context, entities. #{learn_more}" if k == :merge and v.arity != 2
38
+ raise WitException.new "The \'error\' action should take 2 arguments: session_id, msg. #{learn_more}" if k == :error and v.arity != 2
39
+ raise WitException.new "The '#{k}' action should take 1 argument: context. #{learn_more}" if k != :say and k != :merge and k != :error and v.arity != 1
40
+ end
41
+ return actions
42
+ end
43
+
44
+ class Wit
45
+ def initialize(access_token, actions)
46
+ @access_token = access_token
47
+ @actions = validate_actions actions
28
48
  end
29
49
 
30
- def self.message(access_token, msg)
50
+ def message(msg)
31
51
  params = {}
32
- if msg
33
- params[:q] = msg
52
+ params[:q] = msg unless msg.nil?
53
+ req @access_token, Net::HTTP::Get, '/message', params
54
+ end
55
+
56
+ def converse(session_id, msg, context={})
57
+ params = {}
58
+ params[:q] = msg unless msg.nil?
59
+ params[:session_id] = session_id
60
+ req @access_token, Net::HTTP::Post, '/converse', params, context
61
+ end
62
+
63
+ def run_actions(session_id, message, context={}, max_steps=DEFAULT_MAX_STEPS)
64
+ raise WitException.new 'max iterations reached' unless max_steps > 0
65
+
66
+ rst = converse session_id, message, context
67
+ raise WitException.new 'couldn\'t find type in Wit response' unless rst.has_key? 'type'
68
+
69
+ type = rst['type']
70
+
71
+ return context if type == 'stop'
72
+ if type == 'msg'
73
+ raise WitException.new 'unknown action: say' unless @actions.has_key? :say
74
+ msg = rst['msg']
75
+ p "Executing say with: #{msg}"
76
+ @actions[:say].call session_id, msg
77
+ elsif type == 'merge'
78
+ raise WitException.new 'unknown action: merge' unless @actions.has_key? :merge
79
+ p 'Executing merge'
80
+ context = @actions[:merge].call context, rst['entities']
81
+ if context.nil?
82
+ p 'WARN missing context - did you forget to return it?'
83
+ context = {}
84
+ end
85
+ elsif type == 'action'
86
+ action = rst['action'].to_sym
87
+ raise WitException.new "unknown action: #{action}" unless @actions.has_key? action
88
+ p "Executing action #{action}"
89
+ context = @actions[action].call context
90
+ if context.nil?
91
+ p 'WARN missing context - did you forget to return it?'
92
+ context = {}
93
+ end
94
+ elsif type == 'error'
95
+ raise WitException.new 'unknown action: error' unless @actions.has_key? :error
96
+ p 'Executing error'
97
+ @actions[:error].call session_id, 'unknown action: error'
98
+ else
99
+ raise WitException.new "unknown type: #{type}"
34
100
  end
35
- req(access_token, Net::HTTP::Get, '/message', params)
101
+ return run_actions session_id, nil, context, max_steps - 1
36
102
  end
37
103
  end
data/wit.gemspec CHANGED
@@ -1,15 +1,15 @@
1
1
  Gem::Specification.new do |s|
2
- s.name = 'wit'
3
- s.version = '2.0.0'
4
- s.date = '2014-12-05'
5
- s.summary = 'Ruby SDK for Wit.ai'
6
- s.description = 'Ruby SDK for Wit.ai'
7
- s.authors = ['The Wit Team']
8
- s.email = 'help@wit.ai'
9
- s.homepage = 'https://wit.ai'
10
- s.license = 'GPL-2.0'
11
- s.platform = Gem::Platform::RUBY
12
- s.required_ruby_version = '>= 1.9.3'
13
- s.require_paths = ['lib']
14
- s.files = `git ls-files`.split("\n")
2
+ s.name = 'wit'
3
+ s.version = '3.0.0'
4
+ s.date = '2014-12-05'
5
+ s.summary = 'Ruby SDK for Wit.ai'
6
+ s.description = 'Ruby SDK for Wit.ai'
7
+ s.authors = ['The Wit Team']
8
+ s.email = 'help@wit.ai'
9
+ s.homepage = 'https://wit.ai'
10
+ s.license = 'GPL-2.0'
11
+ s.platform = Gem::Platform::RUBY
12
+ s.required_ruby_version = '>= 1.9.3'
13
+ s.require_paths = ['lib']
14
+ s.files = `git ls-files`.split("\n")
15
15
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: wit
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0
4
+ version: 3.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - The Wit Team
@@ -16,10 +16,13 @@ executables: []
16
16
  extensions: []
17
17
  extra_rdoc_files: []
18
18
  files:
19
- - .gitignore
19
+ - ".gitignore"
20
20
  - CHANGES.md
21
21
  - LICENSE
22
22
  - README.md
23
+ - examples/joke.rb
24
+ - examples/quickstart.rb
25
+ - examples/template.rb
23
26
  - lib/wit.rb
24
27
  - wit.gemspec
25
28
  homepage: https://wit.ai
@@ -32,17 +35,17 @@ require_paths:
32
35
  - lib
33
36
  required_ruby_version: !ruby/object:Gem::Requirement
34
37
  requirements:
35
- - - '>='
38
+ - - ">="
36
39
  - !ruby/object:Gem::Version
37
40
  version: 1.9.3
38
41
  required_rubygems_version: !ruby/object:Gem::Requirement
39
42
  requirements:
40
- - - '>='
43
+ - - ">="
41
44
  - !ruby/object:Gem::Version
42
45
  version: '0'
43
46
  requirements: []
44
47
  rubyforge_project:
45
- rubygems_version: 2.0.14.1
48
+ rubygems_version: 2.4.5
46
49
  signing_key:
47
50
  specification_version: 4
48
51
  summary: Ruby SDK for Wit.ai