wit 2.0.0 → 3.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 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