Skip to content
This repository was archived by the owner on Jan 5, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 27 additions & 11 deletions libraries/botbuilder-ai/botbuilder/ai/luis/luis_recognizer.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,7 @@ async def recognize(
turn_context: TurnContext,
telemetry_properties: Dict[str, str] = None,
telemetry_metrics: Dict[str, float] = None,
luis_prediction_options: LuisPredictionOptions = None
) -> RecognizerResult:
"""Return results of the analysis (Suggested actions and intents).

Expand All @@ -168,7 +169,7 @@ async def recognize(
"""

return await self._recognize_internal(
turn_context, telemetry_properties, telemetry_metrics
turn_context, telemetry_properties, telemetry_metrics, luis_prediction_options
)

def on_recognizer_result(
Expand Down Expand Up @@ -288,6 +289,7 @@ async def _recognize_internal(
turn_context: TurnContext,
telemetry_properties: Dict[str, str],
telemetry_metrics: Dict[str, float],
luis_prediction_options: LuisPredictionOptions = None
) -> RecognizerResult:

BotAssert.context_not_none(turn_context)
Expand All @@ -299,6 +301,11 @@ async def _recognize_internal(
recognizer_result: RecognizerResult = None
luis_result: LuisResult = None

if luis_prediction_options:
options = self._merge_options(luis_prediction_options)
else:
options = self._options

if not utterance or utterance.isspace():
recognizer_result = RecognizerResult(
text=utterance, intents={"": IntentScore(score=1.0)}, entities={}
Expand All @@ -307,12 +314,12 @@ async def _recognize_internal(
luis_result = self._runtime.prediction.resolve(
self._application.application_id,
utterance,
timezone_offset=self._options.timezone_offset,
verbose=self._options.include_all_intents,
staging=self._options.staging,
spell_check=self._options.spell_check,
bing_spell_check_subscription_key=self._options.bing_spell_check_subscription_key,
log=self._options.log if self._options.log is not None else True,
timezone_offset=options.timezone_offset,
verbose=options.include_all_intents,
staging=options.staging,
spell_check=options.spell_check,
bing_spell_check_subscription_key=options.bing_spell_check_subscription_key,
log=options.log if options.log is not None else True,
)

recognizer_result = RecognizerResult(
Expand All @@ -322,8 +329,8 @@ async def _recognize_internal(
entities=LuisUtil.extract_entities_and_metadata(
luis_result.entities,
luis_result.composite_entities,
self._options.include_instance_data
if self._options.include_instance_data is not None
options.include_instance_data
if options.include_instance_data is not None
else True,
),
)
Expand All @@ -336,7 +343,7 @@ async def _recognize_internal(
recognizer_result, turn_context, telemetry_properties, telemetry_metrics
)

await self._emit_trace_info(turn_context, luis_result, recognizer_result)
await self._emit_trace_info(turn_context, luis_result, recognizer_result, options)

return recognizer_result

Expand All @@ -345,11 +352,12 @@ async def _emit_trace_info(
turn_context: TurnContext,
luis_result: LuisResult,
recognizer_result: RecognizerResult,
options: LuisPredictionOptions
) -> None:
trace_info: Dict[str, object] = {
"recognizerResult": LuisUtil.recognizer_result_as_dict(recognizer_result),
"luisModel": {"ModelID": self._application.application_id},
"luisOptions": {"Staging": self._options.staging},
"luisOptions": {"Staging": options.staging},
"luisResult": LuisUtil.luis_result_as_dict(luis_result),
}

Expand All @@ -362,3 +370,11 @@ async def _emit_trace_info(
)

await turn_context.send_activity(trace_activity)

def _merge_options(
self,
user_defined_options: LuisPredictionOptions
) -> LuisPredictionOptions:
merged_options = LuisPredictionOptions()
merged_options.__dict__.update(user_defined_options.__dict__)
return merged_options
36 changes: 36 additions & 0 deletions libraries/botbuilder-ai/tests/luis/luis_recognizer_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -635,6 +635,42 @@ async def test_telemetry_no_override_async(self):
self.assertTrue("fromId" in call0_args[1])
self.assertTrue("entities" in call0_args[1])

def test_pass_luis_prediction_options_to_recognizer(self):
# Arrange
my_app = LuisApplication(
LuisRecognizerTest._luisAppId,
LuisRecognizerTest._subscriptionKey,
endpoint=None,
)

luis_prediction_options = LuisPredictionOptions(
log_personal_information=True, include_all_intents=True, include_instance_data=True
)

# Assert
recognizer = LuisRecognizer(my_app)
merged_options = recognizer._merge_options(luis_prediction_options)
self.assertTrue(merged_options.log_personal_information)
self.assertTrue(merged_options.include_all_intents)
self.assertTrue(merged_options.include_instance_data)
self.assertFalse(recognizer._options.log_personal_information)
self.assertFalse(recognizer._options.include_all_intents)
self.assertFalse(recognizer._options.include_instance_data)

def test_dont_pass_luis_prediction_options_to_recognizer(self):
# Arrange
my_app = LuisApplication(
LuisRecognizerTest._luisAppId,
LuisRecognizerTest._subscriptionKey,
endpoint=None,
)

# Assert
recognizer = LuisRecognizer(my_app)
self.assertFalse(recognizer._options.log_personal_information)
self.assertFalse(recognizer._options.include_all_intents)
self.assertFalse(recognizer._options.include_instance_data)

async def test_composite1(self):
await self._test_json("Composite1.json")

Expand Down