xip-luis 1.2.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 870278eff7d1137878825a9e25be8f83c46b45f3763091e6671427f9df6cf75b
4
+ data.tar.gz: 340a78e02e9db834799a49e9ec9d196f6bf7cef20f782d74c3291ed5790548a9
5
+ SHA512:
6
+ metadata.gz: edf4ba99ed57c1ce36c729436675a24df7041d2e4557b621decd9fce3fa4b5858c31f5785eebe0104ab1c3d8deb6fe4708b4d6df0b0aee0172085fdf88b8e3f9
7
+ data.tar.gz: 0fadea07ccdc34a113e750668da7823bebfd710635b8ae1c152723a7c9475015dedea9fa5dfe3f50b7b5c31bf80654558b1468c4badc84b0447f4f78c2ff9628
@@ -0,0 +1,30 @@
1
+ # Changelog 1.2.1
2
+
3
+ ## Features
4
+
5
+ * Updated gems
6
+
7
+ # Changelog 1.2.0
8
+
9
+ ## Bugfixes
10
+
11
+ * `datetimeReference` is not respected by LUIS when specified as a `GET`. Switched to `POST`
12
+ * Renamed `tz_offset` option to `datetime_reference` to more closely match the LUIS API
13
+
14
+ # Changelog 1.1.0
15
+
16
+ ## Features
17
+
18
+ * Added intent threshold option; intents with lower scores than the threshold are not matched.
19
+
20
+ # Changelog 1.0.0
21
+
22
+ ## Bugfixes
23
+
24
+ * The endpoint is now properly configurable
25
+ * Updated gem dependencies
26
+ * Fixed README to point out correct config
27
+
28
+ # Changelog 0.9.0
29
+
30
+ * Initial release
data/Gemfile ADDED
@@ -0,0 +1,3 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gemspec
@@ -0,0 +1,100 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ xip-luis (1.2.1)
5
+ http (~> 4)
6
+ xip (~> 2.0.0.beta)
7
+
8
+ GEM
9
+ remote: https://rubygems.org/
10
+ specs:
11
+ activesupport (6.1.0)
12
+ concurrent-ruby (~> 1.0, >= 1.0.2)
13
+ i18n (>= 1.6, < 2)
14
+ minitest (>= 5.1)
15
+ tzinfo (~> 2.0)
16
+ zeitwerk (~> 2.3)
17
+ addressable (2.7.0)
18
+ public_suffix (>= 2.0.2, < 5.0)
19
+ concurrent-ruby (1.1.7)
20
+ connection_pool (2.2.3)
21
+ diff-lcs (1.4.4)
22
+ domain_name (0.5.20190701)
23
+ unf (>= 0.0.5, < 1.0.0)
24
+ ffi (1.14.2)
25
+ ffi-compiler (1.0.1)
26
+ ffi (>= 1.0.0)
27
+ rake
28
+ http (4.4.1)
29
+ addressable (~> 2.3)
30
+ http-cookie (~> 1.0)
31
+ http-form_data (~> 2.2)
32
+ http-parser (~> 1.2.0)
33
+ http-cookie (1.0.3)
34
+ domain_name (~> 0.5)
35
+ http-form_data (2.3.0)
36
+ http-parser (1.2.2)
37
+ ffi-compiler
38
+ i18n (1.8.5)
39
+ concurrent-ruby (~> 1.0)
40
+ minitest (5.14.2)
41
+ multi_json (1.15.0)
42
+ mustermann (1.1.1)
43
+ ruby2_keywords (~> 0.0.1)
44
+ nio4r (2.5.4)
45
+ public_suffix (4.0.6)
46
+ puma (4.3.7)
47
+ nio4r (~> 2.0)
48
+ rack (2.2.3)
49
+ rack-protection (2.1.0)
50
+ rack
51
+ rake (13.0.3)
52
+ redis (4.2.5)
53
+ rspec (3.9.0)
54
+ rspec-core (~> 3.9.0)
55
+ rspec-expectations (~> 3.9.0)
56
+ rspec-mocks (~> 3.9.0)
57
+ rspec-core (3.9.2)
58
+ rspec-support (~> 3.9.3)
59
+ rspec-expectations (3.9.2)
60
+ diff-lcs (>= 1.2.0, < 2.0)
61
+ rspec-support (~> 3.9.0)
62
+ rspec-mocks (3.9.1)
63
+ diff-lcs (>= 1.2.0, < 2.0)
64
+ rspec-support (~> 3.9.0)
65
+ rspec-support (3.9.3)
66
+ ruby2_keywords (0.0.2)
67
+ sidekiq (6.1.2)
68
+ connection_pool (>= 2.2.2)
69
+ rack (~> 2.0)
70
+ redis (>= 4.2.0)
71
+ sinatra (2.1.0)
72
+ mustermann (~> 1.0)
73
+ rack (~> 2.2)
74
+ rack-protection (= 2.1.0)
75
+ tilt (~> 2.0)
76
+ thor (1.0.1)
77
+ tilt (2.0.10)
78
+ tzinfo (2.0.4)
79
+ concurrent-ruby (~> 1.0)
80
+ unf (0.1.4)
81
+ unf_ext
82
+ unf_ext (0.0.7.7)
83
+ xip (2.0.0.beta2)
84
+ activesupport (~> 6.0)
85
+ multi_json (~> 1.12)
86
+ puma (>= 4.2, < 5.0)
87
+ sidekiq (~> 6.0)
88
+ sinatra (~> 2.0)
89
+ thor (~> 1.0)
90
+ zeitwerk (2.4.2)
91
+
92
+ PLATFORMS
93
+ ruby
94
+
95
+ DEPENDENCIES
96
+ rspec (~> 3)
97
+ xip-luis!
98
+
99
+ BUNDLED WITH
100
+ 2.1.4
data/LICENSE ADDED
@@ -0,0 +1,7 @@
1
+ Copyright (c) 2017-2020 Mauricio Gomes
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4
+
5
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6
+
7
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,314 @@
1
+ # LUIS NLP Xip Kit Component
2
+
3
+ This integration implements the [Microsoft LUIS](https://luis.ai) Language Understanding service. It utilizes the built-in NLP features part of Xip 2.x. If you are still using Xip 1.x, you will first need to upgrade to Xip 2.x before you can use this integration.
4
+
5
+ ## Configuration
6
+
7
+ For instructions on how to configure your Azure account signup for LUIS, please reference their docs. You won't have to set this anywhere, but this gem does utilize the latest `v3` LUIS API version.
8
+
9
+ Once your account is setup, these are the configuration settings you will need to add to you `services.yml` file:
10
+
11
+ ```yaml
12
+ default: &default
13
+ nlp_integration: luis
14
+ luis:
15
+ endpoint: westus.api.cognitive.microsoft.com
16
+ app_id: 9434fbd8-420b-6d75-8a6f-b6c9a0ac5ec0
17
+ subscription_key: 1b69a4b9db669805b4fcba5f1f2f87bb
18
+ tz_offset: 0
19
+ intent_threshold: 0.2
20
+
21
+ production:
22
+ <<: *default
23
+ development:
24
+ <<: *default
25
+ test:
26
+ <<: *default
27
+ ```
28
+
29
+ Xip will automatically use your `staging` LUIS slot in development and staging environments and will use the `production` slot for your production Xip environment.
30
+
31
+ That's it! Xip will now automatically use LUIS for intent detection and entity extraction automatically via `handle_response` and `get_match`.
32
+
33
+ ## Intents
34
+
35
+ We recommend you name your intents using snake case (`snake_case`). This is because this integration will automatically convert your intent names to Ruby symbols.
36
+
37
+ So for example, if you have a `handle_response` defined like this:
38
+
39
+ ```ruby
40
+ handle_response(
41
+ 'Maybe' => proc { step_to state: :say_maybe },
42
+ :yes => proc { step_to state: :say_yes },
43
+ :no => proc { step_to state: :say_no }
44
+ )
45
+ ```
46
+
47
+ If your user responds with a variation of the string `maybe`, then they will be taken to the state `say_maybe`.
48
+
49
+ Otherwise, the intent named `yes` and the intent named `no` will attempt to be matched. So if you had named your intent `YES` for example, you'd have to use `:YES` here which doesn't match Ruby syntax conventions.
50
+
51
+ For more info about how intents are matched, please see the [Xip Kit NLP documentation](https://docs.xipkit.com/nlp).
52
+
53
+ ### intent_threshold
54
+
55
+ This is the real number that respresents the minimum threshold required for an intent to match. So if for example your `intent_threshold` is set to `0.2`, if the top intent scores `0.09`, it will not be returned as a match.
56
+
57
+ ## Entities
58
+
59
+ The entity types listed below are named using their corresponding Xip type. The equivalent type used by Microsoft LUIS is also listed. For each code sample, the sample query is first provided followed by the array of entities extracted from the queries (for the given type).
60
+
61
+ It's possible, and even likely, that a query matches more than one entity type. For example, a `currency` type will also match a `number` type. For more info about how to utilize these types, please see the [Xip Kit NLP documentation](https://docs.xipkit.com/nlp).
62
+
63
+ ### number
64
+
65
+ LUIS prebuilt entity: `number`
66
+
67
+ ```ruby
68
+ "I think it was something like 63 or maybe 764"
69
+
70
+ [
71
+ 63,
72
+ 764
73
+ ]
74
+ ```
75
+
76
+ ```ruby
77
+ "It was almost 15k"
78
+
79
+ [
80
+ 15000
81
+ ]
82
+ ```
83
+
84
+ For more info about these values, please reference the [number entity LUIS documentation](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-reference-prebuilt-number?tabs=V3).
85
+
86
+ ### currency
87
+
88
+ LUIS prebuilt entity: `money`
89
+
90
+ ```ruby
91
+ "send me $87 or 48 cents"
92
+
93
+ [
94
+ { 'number' => 87, 'units' => 'Dollar' },
95
+ { 'number' => 48, 'units': 'Cent' }
96
+ ]
97
+ ```
98
+
99
+ For more info about these values, please reference the [money entity LUIS documentation](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-reference-prebuilt-currency?tabs=V3).
100
+
101
+ ### email
102
+
103
+ LUIS prebuilt entity: `email`
104
+
105
+ ```ruby
106
+ "you can contact me at john@email.none"
107
+
108
+ [
109
+ "john@email.none"
110
+ ]
111
+ ```
112
+
113
+ For more info about these values, please reference the [email entity LUIS documentation](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-reference-prebuilt-email?tabs=V3).
114
+
115
+ ### phone
116
+
117
+ LUIS prebuilt entity: `phonenumber`
118
+
119
+ Note: LUIS does not parse nor attempts to clean up phone number.
120
+
121
+ ```ruby
122
+ "You can reach me at 313-555-1212"
123
+
124
+ [
125
+ "313-555-1212"
126
+ ]
127
+ ```
128
+
129
+ For more info about these values, please reference the [phonenumber entity LUIS documentation](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-reference-prebuilt-phonenumber?tabs=V3).
130
+
131
+ ### percentage
132
+
133
+ LUIS prebuilt entity: `percentage`
134
+
135
+ ```ruby
136
+ "The stock is up 8.9% today"
137
+
138
+ [
139
+ 8.9
140
+ ]
141
+ ```
142
+
143
+ For more info about these values, please reference the [percentage entity LUIS documentation](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-reference-prebuilt-percentage?tabs=V3).
144
+
145
+ ### age
146
+
147
+ LUIS prebuilt entity: `age`
148
+
149
+ ```ruby
150
+ "81 years old"
151
+
152
+ [
153
+ { 'number' => 81, 'units' => 'Year' }
154
+ ]
155
+ ```
156
+
157
+ For more info about these values, please reference the [age entity LUIS documentation](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-reference-prebuilt-age?tabs=V3).
158
+
159
+ ### url
160
+
161
+ LUIS prebuilt entity: `url`
162
+
163
+ ```ruby
164
+ "please visit google.com or https://google.com"
165
+
166
+ [
167
+ "google.com",
168
+ "https://google.com"
169
+ ]
170
+
171
+ ```
172
+
173
+ For more info about these values, please reference the [url entity LUIS documentation](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-reference-prebuilt-url?tabs=V3).
174
+
175
+ ### ordinal
176
+
177
+ LUIS prebuilt entity: `ordinalV2`
178
+
179
+ ```ruby
180
+ "they finished 2nd and 5th"
181
+
182
+ [
183
+ { 'offset' => 2, 'relativeTo' => 'start' },
184
+ { 'offset' => 5, 'relativeTo' => 'start' }
185
+ ]
186
+ ```
187
+
188
+ ```ruby
189
+ "she finished last"
190
+
191
+ [
192
+ { 'offset' => 0, 'relativeTo' => 'end' }
193
+ ]
194
+ ```
195
+
196
+ For more info about these values, please reference the [ordinalV2 entity LUIS documentation](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-reference-prebuilt-ordinal-v2?tabs=V3).
197
+
198
+ ### geo
199
+
200
+ LUIS prebuilt entity: `geographyV2`
201
+
202
+ ```ruby
203
+ "She moved to paris, france"
204
+
205
+ [
206
+ { 'value' => 'paris', 'type' => 'city' },
207
+ { 'value' => 'france', 'type' => 'countryRegion' }
208
+ ]
209
+ ```
210
+
211
+ For more info about these values, please reference the [geographyV2 entity LUIS documentation](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-reference-prebuilt-geographyv2?tabs=V3).
212
+
213
+ ### dimension
214
+
215
+ LUIS prebuilt entity: `dimension`
216
+
217
+ ```ruby
218
+ "it's about 4 inches wide"
219
+
220
+ [
221
+ { "number": 4, "units": "Inch" }
222
+ ]
223
+ ```
224
+
225
+ For more info about these values, please reference the [dimension entity LUIS documentation](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-reference-prebuilt-dimension?tabs=V3).
226
+
227
+ ### temp
228
+
229
+ LUIS prebuilt entity: `temperature`
230
+
231
+ ```ruby
232
+ "it feels like 98 degrees"
233
+
234
+ [
235
+ { 'number' => 98, 'units' => 'Degree' }
236
+ ]
237
+ ```
238
+
239
+ For more info about these values, please reference the [temperature entity LUIS documentation](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-reference-prebuilt-temperature?tabs=V3).
240
+
241
+ ### datetime
242
+
243
+ LUIS prebuilt entity: `datetimeV2`
244
+
245
+ This one is the most complicated one to work with. The values are nested pretty deeply. This integration exposes the values at such a high level because there is a chance that LUIS will return results for more than one date type. For example, below we have just one result of type `date`, but LUIS could return more than one object of subtype `daterange`, `time`, `timerange`, etc. See the docs for more info about these subtypes.
246
+
247
+ ```ruby
248
+ "How about Mar 12?"
249
+
250
+ [
251
+ {
252
+ "type": "date",
253
+ "values": [
254
+ {
255
+ "timex": "XXXX-03-12",
256
+ "resolution": [
257
+ {
258
+ "value": "2019-03-12"
259
+ },
260
+ {
261
+ "value": "2020-03-12"
262
+ }
263
+ ]
264
+ }
265
+ ]
266
+ }
267
+ ]
268
+ ```
269
+
270
+ For more info about these values, please reference the [datetimeV2 entity LUIS documentation](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-reference-prebuilt-datetimev2?tabs=1-1%2C2-1%2C3-1%2C4-1%2C5-1%2C6-1#types-of-datetimev2).
271
+
272
+ ### duration
273
+
274
+ LUIS prebuilt domain entity: `Calendar.Duration`
275
+
276
+ ```ruby
277
+ "it will be between 15 minutes and 3 hours"
278
+
279
+ [
280
+ "15 minutes",
281
+ "3 hours"
282
+ ]
283
+ ```
284
+
285
+ _Additional docs for this prebuilt domain entitiy is not available_
286
+
287
+ ### key_phrase
288
+
289
+ LUIS prebuilt entity: `keyPhrase`
290
+
291
+ ```ruby
292
+ "I need to find the instructional materials for the course"
293
+
294
+ [
295
+ "instructional materials",
296
+ "course"
297
+ ]
298
+ ```
299
+
300
+ For more info about these values, please reference the [keyPhrase entity LUIS documentation](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-reference-prebuilt-keyphrase?tabs=V3).
301
+
302
+ ### name
303
+
304
+ LUIS prebuilt entity: `personName`
305
+
306
+ ```ruby
307
+ "Little Cindy-Lou Who who was not more than two"
308
+
309
+ [
310
+ "Little Cindy-Lou"
311
+ ]
312
+ ```
313
+
314
+ For more info about these values, please reference the [personName entity LUIS documentation](https://docs.microsoft.com/en-us/azure/cognitive-services/luis/luis-reference-prebuilt-person?tabs=V3).
@@ -0,0 +1,3 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'xip/nlp/luis'
@@ -0,0 +1,4 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'xip/nlp/luis/result'
4
+ require 'xip/nlp/luis/client'
@@ -0,0 +1,62 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Xip
4
+ module Nlp
5
+ module Luis
6
+ class Client < Xip::Nlp::Client
7
+
8
+ def initialize(subscription_key: nil, app_id: nil, endpoint: nil, datetime_ref: nil)
9
+ begin
10
+ @subscription_key = subscription_key || Xip.config.luis.subscription_key
11
+ @app_id = app_id || Xip.config.luis.app_id
12
+ @endpoint = endpoint || Xip.config.luis.endpoint
13
+ @datetime_ref = datetime_ref || Xip.config.luis.datetime_reference
14
+ @slot = Xip.env.development? ? 'staging' : 'production'
15
+ rescue NoMethodError
16
+ raise(
17
+ Xip::Errors::ConfigurationError,
18
+ 'A `luis` configuration key must be specified directly or in `services.yml`'
19
+ )
20
+ end
21
+ end
22
+
23
+ def endpoint
24
+ "https://#{@endpoint}/luis/prediction/v3.0/apps/#{@app_id}/slots/#{@slot}/predict"
25
+ end
26
+
27
+ def client
28
+ @client ||= begin
29
+ headers = {
30
+ 'Content-Type' => 'application/json'
31
+ }
32
+ HTTP.timeout(connect: 15, read: 60).headers(headers)
33
+ end
34
+ end
35
+
36
+ def understand(query:)
37
+ params = {
38
+ 'subscription-key' => @subscription_key
39
+ }
40
+
41
+ body = MultiJson.dump({
42
+ 'query' => query,
43
+ 'options' => {
44
+ 'datetimeReference' => @datetime_ref,
45
+ }
46
+ })
47
+
48
+ Xip::Logger.l(
49
+ topic: :nlp,
50
+ message: 'Performing NLP lookup via Microsoft LUIS'
51
+ )
52
+ result = client.post(endpoint, params: params, body: body)
53
+ Result.new(result: result)
54
+ end
55
+
56
+ end
57
+ end
58
+ end
59
+ end
60
+
61
+ ENTITY_TYPES = %i(number currency email percentage phone age
62
+ url ordinal geo dimension temp datetime duration)
@@ -0,0 +1,131 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Xip
4
+ module Nlp
5
+ module Luis
6
+ class Result < Xip::Nlp::Result
7
+
8
+ ENTITY_MAP = {
9
+ 'money' => :currency, 'number' => :number, 'email' => :email,
10
+ 'percentage' => :percentage, 'Calendar.Duration' => :duration,
11
+ 'geographyV2' => :geo, 'age' => :age, 'phonenumber' => :phone,
12
+ 'ordinalV2' => :ordinal, 'url' => :url, 'dimension' => :dimension,
13
+ 'temperature' => :temp, 'keyPhrase' => :key_phrase, 'name' => :name,
14
+ 'datetimeV2' => :datetime
15
+ }
16
+
17
+ def initialize(result:)
18
+ @result = result
19
+ if result.status.success?
20
+ Xip::Logger.l(
21
+ topic: :nlp,
22
+ message: 'NLP lookup successful'
23
+ )
24
+ parsed_result
25
+ else
26
+ Xip::Logger.l(
27
+ topic: :nlp,
28
+ message: "NLP lookup FAILED: (#{result.status.code}) #{result.body.to_s}"
29
+ )
30
+ end
31
+ end
32
+
33
+ # Sample JSON result:
34
+ # {
35
+ # "query": "I make between $5400 and $9600 per month",
36
+ # "prediction": {
37
+ # "topIntent": "None",
38
+ # "intents": {
39
+ # "None": {
40
+ # "score": 0.5345857
41
+ # }
42
+ # },
43
+ # "entities": {
44
+ # "money": [
45
+ # {
46
+ # "number": 5400,
47
+ # "units": "Dollar"
48
+ # },
49
+ # {
50
+ # "number": 9600,
51
+ # "units": "Dollar"
52
+ # }
53
+ # ],
54
+ # "number": [
55
+ # 5400,
56
+ # 9600
57
+ # ]
58
+ # },
59
+ # "sentiment": {
60
+ # "label": "positive",
61
+ # "score": 0.7805586
62
+ # }
63
+ # }
64
+ # }
65
+ def parsed_result
66
+ @parsed_result ||= MultiJson.load(result.body.to_s)
67
+ end
68
+
69
+ def intent
70
+ top_intent&.to_sym
71
+ end
72
+
73
+ def intent_score
74
+ parsed_result&.dig('prediction', 'intents', top_intent, 'score')
75
+ end
76
+
77
+ def raw_entities
78
+ parsed_result&.dig('prediction', 'entities')
79
+ end
80
+
81
+ def entities
82
+ return {} if raw_entities.blank?
83
+ _entities = {}
84
+
85
+ raw_entities.each do |type, values|
86
+ if ENTITY_MAP[type]
87
+ _entities[ENTITY_MAP[type]] = values
88
+ else
89
+ # A custom entity
90
+ _entities[type.to_sym] = values
91
+ end
92
+ end
93
+
94
+ _entities
95
+ end
96
+
97
+ def sentiment_score
98
+ parsed_result&.dig('prediction', 'sentiment', 'score')
99
+ end
100
+
101
+ def sentiment
102
+ parsed_result&.dig('prediction', 'sentiment', 'label')&.to_sym
103
+ end
104
+
105
+ private
106
+
107
+ def top_intent
108
+ @top_intent ||= begin
109
+ matched_intent = parsed_result&.dig('prediction', 'topIntent')
110
+ _intent_score = parsed_result&.dig('prediction', 'intents', matched_intent, 'score')
111
+
112
+ if Xip.config.luis.intent_threshold.is_a?(Numeric)
113
+ if _intent_score > Xip.config.luis.intent_threshold
114
+ matched_intent
115
+ else
116
+ Xip::Logger.l(
117
+ topic: :nlp,
118
+ message: "Ignoring intent match. Does not meet threshold (#{Xip.config.luis.intent_threshold})"
119
+ )
120
+ 'None' # can't be nil or this doesn't get memoized
121
+ end
122
+ else
123
+ matched_intent
124
+ end
125
+ end
126
+ end
127
+
128
+ end
129
+ end
130
+ end
131
+ end
@@ -0,0 +1,84 @@
1
+ $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
+ $LOAD_PATH.unshift(File.dirname(__FILE__))
3
+
4
+ require 'rspec'
5
+ require 'xip-luis'
6
+
7
+ RSpec.configure do |config|
8
+ config.expect_with :rspec do |expectations|
9
+ # This option will default to `true` in RSpec 4. It makes the `description`
10
+ # and `failure_message` of custom matchers include text for helper methods
11
+ # defined using `chain`, e.g.:
12
+ # be_bigger_than(2).and_smaller_than(4).description
13
+ # # => "be bigger than 2 and smaller than 4"
14
+ # ...rather than:
15
+ # # => "be bigger than 2"
16
+ expectations.include_chain_clauses_in_custom_matcher_descriptions = true
17
+ end
18
+
19
+ # rspec-mocks config goes here. You can use an alternate test double
20
+ # library (such as bogus or mocha) by changing the `mock_with` option here.
21
+ config.mock_with :rspec do |mocks|
22
+ # Prevents you from mocking or stubbing a method that does not exist on
23
+ # a real object. This is generally recommended, and will default to
24
+ # `true` in RSpec 4.
25
+ mocks.verify_partial_doubles = true
26
+ end
27
+
28
+ # This option will default to `:apply_to_host_groups` in RSpec 4 (and will
29
+ # have no way to turn it off -- the option exists only for backwards
30
+ # compatibility in RSpec 3). It causes shared context metadata to be
31
+ # inherited by the metadata hash of host groups and examples, rather than
32
+ # triggering implicit auto-inclusion in groups with matching metadata.
33
+ config.shared_context_metadata_behavior = :apply_to_host_groups
34
+
35
+ # The settings below are suggested to provide a good initial experience
36
+ # with RSpec, but feel free to customize to your heart's content.
37
+ =begin
38
+ # This allows you to limit a spec run to individual examples or groups
39
+ # you care about by tagging them with `:focus` metadata. When nothing
40
+ # is tagged with `:focus`, all examples get run. RSpec also provides
41
+ # aliases for `it`, `describe`, and `context` that include `:focus`
42
+ # metadata: `fit`, `fdescribe` and `fcontext`, respectively.
43
+ config.filter_run_when_matching :focus
44
+
45
+ # Allows RSpec to persist some state between runs in order to support
46
+ # the `--only-failures` and `--next-failure` CLI options. We recommend
47
+ # you configure your source control system to ignore this file.
48
+ config.example_status_persistence_file_path = "spec/examples.txt"
49
+
50
+ # Limits the available syntax to the non-monkey patched syntax that is
51
+ # recommended. For more details, see:
52
+ # - http://rspec.info/blog/2012/06/rspecs-new-expectation-syntax/
53
+ # - http://www.teaisaweso.me/blog/2013/05/27/rspecs-new-message-expectation-syntax/
54
+ # - http://rspec.info/blog/2014/05/notable-changes-in-rspec-3/#zero-monkey-patching-mode
55
+ config.disable_monkey_patching!
56
+
57
+ # Many RSpec users commonly either run the entire suite or an individual
58
+ # file, and it's useful to allow more verbose output when running an
59
+ # individual spec file.
60
+ if config.files_to_run.one?
61
+ # Use the documentation formatter for detailed output,
62
+ # unless a formatter has already been configured
63
+ # (e.g. via a command-line flag).
64
+ config.default_formatter = 'doc'
65
+ end
66
+
67
+ # Print the 10 slowest examples and example groups at the
68
+ # end of the spec run, to help surface which specs are running
69
+ # particularly slow.
70
+ config.profile_examples = 10
71
+
72
+ # Run specs in random order to surface order dependencies. If you find an
73
+ # order dependency and want to debug it, you can fix the order by providing
74
+ # the seed, which is printed after each run.
75
+ # --seed 1234
76
+ config.order = :random
77
+
78
+ # Seed global randomization in this process using the `--seed` CLI option.
79
+ # Setting this allows you to use `--seed` to deterministically reproduce
80
+ # test failures related to randomization by passing the same `--seed` value
81
+ # as the one that triggered the failure.
82
+ Kernel.srand config.seed
83
+ =end
84
+ end
@@ -0,0 +1,22 @@
1
+ $LOAD_PATH.push File.expand_path('../lib', __FILE__)
2
+
3
+ Gem::Specification.new do |s|
4
+ s.name = 'xip-luis'
5
+ s.version = '1.2.1'
6
+ s.summary = "LUIS NLP Xip Kit Component"
7
+ s.description = "Built-in NLP for Xip Kit via Microsoft's Language Understanding (LUIS)."
8
+ s.authors = ["Mauricio Gomes"]
9
+ s.email = 'mauricio@edge14.com'
10
+ s.homepage = 'http://github.com/xipkit/xip-luis'
11
+ s.license = 'MIT'
12
+
13
+ s.add_dependency 'xip', '~> 2.0.0.beta'
14
+ s.add_dependency 'http', '~> 4'
15
+
16
+ s.add_development_dependency "rspec", "~> 3"
17
+
18
+ s.files = `git ls-files`.split("\n")
19
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
20
+ s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
21
+ s.require_paths = ['lib']
22
+ end
metadata ADDED
@@ -0,0 +1,96 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: xip-luis
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.2.1
5
+ platform: ruby
6
+ authors:
7
+ - Mauricio Gomes
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2020-12-23 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: xip
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: 2.0.0.beta
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: 2.0.0.beta
27
+ - !ruby/object:Gem::Dependency
28
+ name: http
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '4'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '4'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3'
55
+ description: Built-in NLP for Xip Kit via Microsoft's Language Understanding (LUIS).
56
+ email: mauricio@edge14.com
57
+ executables: []
58
+ extensions: []
59
+ extra_rdoc_files: []
60
+ files:
61
+ - CHANGELOG.md
62
+ - Gemfile
63
+ - Gemfile.lock
64
+ - LICENSE
65
+ - README.md
66
+ - lib/xip-luis.rb
67
+ - lib/xip/nlp/luis.rb
68
+ - lib/xip/nlp/luis/client.rb
69
+ - lib/xip/nlp/luis/result.rb
70
+ - spec/spec_helper.rb
71
+ - xip-luis.gemspec
72
+ homepage: http://github.com/xipkit/xip-luis
73
+ licenses:
74
+ - MIT
75
+ metadata: {}
76
+ post_install_message:
77
+ rdoc_options: []
78
+ require_paths:
79
+ - lib
80
+ required_ruby_version: !ruby/object:Gem::Requirement
81
+ requirements:
82
+ - - ">="
83
+ - !ruby/object:Gem::Version
84
+ version: '0'
85
+ required_rubygems_version: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ">="
88
+ - !ruby/object:Gem::Version
89
+ version: '0'
90
+ requirements: []
91
+ rubygems_version: 3.1.2
92
+ signing_key:
93
+ specification_version: 4
94
+ summary: LUIS NLP Xip Kit Component
95
+ test_files:
96
+ - spec/spec_helper.rb