10000 Merge branch 'master' into trboehre/expectReplies · ericmicrofocus/botbuilder-python@ea97656 · GitHub
[go: up one dir, main page]

Skip to content

Commit ea97656

Browse files
authored
Merge branch 'master' into trboehre/expectReplies
2 parents 4a84deb + 8b18ba4 commit ea97656

27 files changed

+6785
-110
lines changed

libraries/botbuilder-ai/botbuilder/ai/luis/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,14 @@
22
# Licensed under the MIT License.
33

44
from .luis_application import LuisApplication
5+
from .luis_recognizer_options_v3 import LuisRecognizerOptionsV3
56
from .luis_prediction_options import LuisPredictionOptions
67
from .luis_telemetry_constants import LuisTelemetryConstants
78
from .luis_recognizer import LuisRecognizer
89

910
__all__ = [
1011
"LuisApplication",
12+
"LuisRecognizerOptionsV3",
1113
"LuisPredictionOptions",
1214
"LuisRecognizer",
1315
"LuisTelemetryConstants",

libraries/botbuilder-ai/botbuilder/ai/luis/luis_recognizer.py

Lines changed: 50 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,6 @@
33

44
import json
55
from typing import Dict, List, Tuple, Union
6-
7-
from azure.cognitiveservices.language.luis.runtime import LUISRuntimeClient
8-
from azure.cognitiveservices.language.luis.runtime.models import LuisResult
9-
from msrest.authentication import CognitiveServicesCredentials
10-
116
from botbuilder.core import (
127
BotAssert,
138
IntentScore,
@@ -16,10 +11,11 @@
1611
TurnContext,
1712
)
1813
from botbuilder.schema import ActivityTypes
19-
2014
from . import LuisApplication, LuisPredictionOptions, LuisTelemetryConstants
21-
from .activity_util import ActivityUtil
22-
from .luis_util import LuisUtil
15+
from .luis_recognizer_v3 import LuisRecognizerV3
16+
from .luis_recognizer_v2 import LuisRecognizerV2
17+
from .luis_recognizer_options_v2 import LuisRecognizerOptionsV2
18+
from .luis_recognizer_options_v3 import LuisRecognizerOptionsV3
2319

2420

2521
class LuisRecognizer(Recognizer):
@@ -36,7 +32,9 @@ class LuisRecognizer(Recognizer):
3632
def __init__(
3733
self,
3834
application: Union[LuisApplication, str],
39-
prediction_options: LuisPredictionOptions = None,
35+
prediction_options: Union[
36+
LuisRecognizerOptionsV2, LuisRecognizerOptionsV3, LuisPredictionOptions
37+
] = None,
4038
include_api_results: bool = False,
4139
):
4240
"""Initializes a new instance of the <see cref="LuisRecognizer"/> class.
@@ -59,17 +57,17 @@ def __init__(
5957
)
6058

6159
self._options = prediction_options or LuisPredictionOptions()
62-
63-
self._include_api_results = include_api_results
60+
self._include_api_results = include_api_results or (
61+
prediction_options.include_api_results
62+
if isinstance(
63+
prediction_options, (LuisRecognizerOptionsV3, LuisRecognizerOptionsV2)
64+
)
65+
else False
66+
)
6467

6568
self.telemetry_client = self._options.telemetry_client
6669
self.log_personal_information = self._options.log_personal_information
6770

68-
credentials = CognitiveServicesCredentials(self._application.endpoint_key)
69-
self._runtime = LUISRuntimeClient(self._application.endpoint, credentials)
70-
self._runtime.config.add_user_agent(LuisUtil.get_user_agent())
71-
self._runtime.config.connection.timeout = self._options.timeout // 1000
72-
7371
@staticmethod
7472
def top_intent(
7573
results: RecognizerResult, default_intent: str = "None", min_score: float = 0.0
@@ -249,7 +247,9 @@ async def _recognize_internal(
249247
turn_context: TurnContext,
250248
telemetry_properties: Dict[str, str],
251249
telemetry_metrics: Dict[str, float],
252-
luis_prediction_options: LuisPredictionOptions = None,
250+
luis_prediction_options: Union[
251+
LuisPredictionOptions, LuisRecognizerOptionsV2, LuisRecognizerOptionsV3
252+
] = None,
253253
) -> RecognizerResult:
254254

255255
BotAssert.context_not_none(turn_context)
@@ -259,10 +259,9 @@ async def _recognize_internal(
259259

260260
utterance: str = turn_context.activity.text if turn_context.activity is not None else None
261261
recognizer_result: RecognizerResult = None
262-
luis_result: LuisResult = None
263262

264263
if luis_prediction_options:
265-
options = self._merge_options(luis_prediction_options)
264+
options = luis_prediction_options
266265
else:
267266
options = self._options
268267

@@ -271,71 +270,49 @@ async def _recognize_internal(
271270
text=utterance, intents={"": IntentScore(score=1.0)}, entities={}
272271
)
273272
else:
274-
luis_result = self._runtime.prediction.resolve(
275-
self._application.application_id,
276-
utterance,
277-
timezone_offset=options.timezone_offset,
278-
verbose=options.include_all_intents,
279-
staging=options.staging,
280-
spell_check=options.spell_check,
281-
bing_spell_check_subscription_key=options.bing_spell_check_subscription_key,
282-
log=options.log if options.log is not None else True,
283-
)
284273

285-
recognizer_result = RecognizerResult(
286-
text=utterance,
287-
altered_text=luis_result.altered_query,
288-
intents=LuisUtil.get_intents(luis_result),
289-
entities=LuisUtil.extract_entities_and_metadata(
290-
luis_result.entities,
291-
luis_result.composite_entities,
292-
options.include_instance_data
293-
if options.include_instance_data is not None
294-
else True,
295-
),
296-
)
297-
LuisUtil.add_properties(luis_result, recognizer_result)
298-
if self._include_api_results:
299-
recognizer_result.properties["luisResult"] = luis_result
274+
luis_recognizer = self._build_recognizer(options)
275+
recognizer_result = await luis_recognizer.recognizer_internal(turn_context)
300276

301277
# Log telemetry
302278
self.on_recognizer_result(
303279
recognizer_result, turn_context, telemetry_properties, telemetry_metrics
304280
)
305281

306-
await self._emit_trace_info(
307-
turn_context, luis_result, recognizer_result, options
308-
)
309-
310282
return recognizer_result
311283

312-
async def _emit_trace_info(
313-
self,
314-
turn_context: TurnContext,
315-
luis_result: LuisResult,
316-
recognizer_result: RecognizerResult,
317-
options: LuisPredictionOptions,
318-
) -> None:
319-
trace_info: Dict[str, object] = {
320-
"recognizerResult": LuisUtil.recognizer_result_as_dict(recognizer_result),
321-
"luisModel": {"ModelID": self._application.application_id},
322-
"luisOptions": {"Staging": options.staging},
323-
"luisResult": LuisUtil.luis_result_as_dict(luis_result),
324-
}
325-
326-
trace_activity = ActivityUtil.create_trace(
327-
turn_context.activity,
328-
"LuisRecognizer",
329-
trace_info,
330-
LuisRecognizer.luis_trace_type,
331-
LuisRecognizer.luis_trace_label,
332-
)
333-
334-
await turn_context.send_activity(trace_activity)
335-
336284
def _merge_options(
337-
self, user_defined_options: LuisPredictionOptions
285+
self,
286+
user_defined_options: Union[
287+
LuisRecognizerOptionsV3, LuisRecognizerOptionsV2, LuisPredictionOptions
288+
],
338289
) -> LuisPredictionOptions:
339290
merged_options = LuisPredictionOptions()
340291
merged_options.__dict__.update(user_defined_options.__dict__)
341292
return merged_options
293+
294+
def _build_recognizer(
295+
self,
296+
luis_prediction_options: Union[
297+
LuisRecognizerOptionsV3, LuisRecognizerOptionsV2, LuisPredictionOptions
298+
],
299+
):
300+
if isinstance(luis_prediction_options, LuisRecognizerOptionsV3):
301+
return LuisRecognizerV3(self._application, luis_prediction_options)
302+
if isinstance(luis_prediction_options, LuisRecognizerOptionsV2):
303+
return LuisRecognizerV3(self._application, luis_prediction_options)
304+
305+
recognizer_options = LuisRecognizerOptionsV2(
306+
luis_prediction_options.bing_spell_check_subscription_key,
307+
luis_prediction_options.include_all_intents,
308+
luis_prediction_options.include_instance_data,
309+
luis_prediction_options.log,
310+
luis_prediction_options.spell_check,
311+
luis_prediction_options.staging,
312+
luis_prediction_options.timeout,
313+
luis_prediction_options.timezone_offset,
314+
self._include_api_results,
315+
luis_prediction_options.telemetry_client,
316+
luis_prediction_options.log_personal_information,
317+
)
318+
return LuisRecognizerV2(self._application, recognizer_options)
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
from abc import ABC, abstractmethod
5+
from botbuilder.core import TurnContext
6+
from .luis_application import LuisApplication
7+
8+
9+
class LuisRecognizerInternal(ABC):
10+
def __init__(self, luis_application: LuisApplication):
11+
if luis_application is None:
12+
raise TypeError(luis_application.__class__.__name__)
13+
14+
self.luis_application = luis_application
15+
16+
@abstractmethod
17+
async def recognizer_internal(self, turn_context: TurnContext):
18+
raise NotImplementedError()
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
from botbuilder.core import BotTelemetryClient, NullTelemetryClient
5+
6+
7+
class LuisRecognizerOptions:
8+
def __init__(
9+
self,
10+
include_api_results: bool = None,
11+
telemetry_client: BotTelemetryClient = NullTelemetryClient(),
12+
log_personal_information: bool = False,
13+
):
14+
self.include_api_results = include_api_results
15+
self.telemetry_client = telemetry_client
16+
self.log_personal_information = log_personal_information
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
from botbuilder.core import BotTelemetryClient, NullTelemetryClient
5+
from .luis_recognizer_options import LuisRecognizerOptions
6+
7+
8+
class LuisRecognizerOptionsV2(LuisRecognizerOptions):
9+
def __init__(
10+
self,
11+
bing_spell_check_subscription_key: str = None,
12+
include_all_intents: bool = None,
13+
include_instance_data: bool = True,
14+
log: bool = True,
15+
spell_check: bool = None,
16+
staging: bool = None,
17+
timeout: float = 100000,
18+
timezone_offset: float = None,
19+
include_api_results: bool = True,
20+
telemetry_client: BotTelemetryClient = NullTelemetryClient(),
21+
log_personal_information: bool = False,
22+
):
23+
super().__init__(
24+
include_api_results, telemetry_client, log_personal_information
25+
)
26+
self.bing_spell_check_subscription_key = bing_spell_check_subscription_key
27+
self.include_all_intents = include_all_intents
28+
self.include_instance_data = include_instance_data
29+
self.log = log
30+
self.spell_check = spell_check
31+
self.staging = staging
32+
self.timeout = timeout
33+
self.timezone_offset = timezone_offset
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
# Copyright (c) Microsoft Corporation. All rights reserved.
2+
# Licensed under the MIT License.
3+
4+
from typing import List
5+
6+
from botbuilder.core import BotTelemetryClient, NullTelemetryClient
7+
from .luis_recognizer_options import LuisRecognizerOptions
8+
9+
10+
class LuisRecognizerOptionsV3(LuisRecognizerOptions):
11+
def __init__(
12+
self,
13+
include_all_intents: bool = False,
14+
include_instance_data: bool = True,
15+
log: bool = True,
16+
prefer_external_entities: bool = True,
17+
datetime_reference: str = None,
18+
dynamic_lists: List = None,
19+
external_entities: List = None,
20+
slot: str = "production",
21+
version: str = None,
22+
include_api_results: bool = True,
23+
telemetry_client: BotTelemetryClient = NullTelemetryClient(),
24+
log_personal_information: bool = False,
25+
):
26+
super().__init__(
27+
include_api_results, telemetry_client, log_personal_information
28+
)
29+
self.include_all_intents = include_all_intents
30+
self.include_instance_data = include_instance_data
31+
self.log = log
32+
self.prefer_external_entities = prefer_external_entities
33+
self.datetime_reference = datetime_reference
34+
self.dynamic_lists = dynamic_lists
35+
self.external_entities = external_entities
36+
self.slot = slot
37+
self.version: str = version

0 commit comments

Comments
 (0)
0