microsoft-agents-hosting-dialogs 0.10.0.dev2__py3-none-any.whl

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.
Files changed (91) hide show
  1. microsoft_agents/hosting/dialogs/__init__.py +76 -0
  2. microsoft_agents/hosting/dialogs/_component_registration.py +30 -0
  3. microsoft_agents/hosting/dialogs/_telemetry_client.py +78 -0
  4. microsoft_agents/hosting/dialogs/choices/__init__.py +38 -0
  5. microsoft_agents/hosting/dialogs/choices/channel.py +121 -0
  6. microsoft_agents/hosting/dialogs/choices/choice_factory.py +262 -0
  7. microsoft_agents/hosting/dialogs/choices/choice_recognizer.py +148 -0
  8. microsoft_agents/hosting/dialogs/choices/find.py +242 -0
  9. microsoft_agents/hosting/dialogs/choices/models/__init__.py +23 -0
  10. microsoft_agents/hosting/dialogs/choices/models/choice.py +14 -0
  11. microsoft_agents/hosting/dialogs/choices/models/choice_factory_options.py +13 -0
  12. microsoft_agents/hosting/dialogs/choices/models/find_choices_options.py +28 -0
  13. microsoft_agents/hosting/dialogs/choices/models/find_values_options.py +31 -0
  14. microsoft_agents/hosting/dialogs/choices/models/found_choice.py +22 -0
  15. microsoft_agents/hosting/dialogs/choices/models/found_value.py +20 -0
  16. microsoft_agents/hosting/dialogs/choices/models/list_style.py +15 -0
  17. microsoft_agents/hosting/dialogs/choices/models/model_result.py +16 -0
  18. microsoft_agents/hosting/dialogs/choices/models/sorted_value.py +16 -0
  19. microsoft_agents/hosting/dialogs/choices/models/token.py +20 -0
  20. microsoft_agents/hosting/dialogs/choices/tokenizer.py +92 -0
  21. microsoft_agents/hosting/dialogs/component_dialog.py +284 -0
  22. microsoft_agents/hosting/dialogs/dialog.py +198 -0
  23. microsoft_agents/hosting/dialogs/dialog_component_registration.py +52 -0
  24. microsoft_agents/hosting/dialogs/dialog_container.py +31 -0
  25. microsoft_agents/hosting/dialogs/dialog_context.py +426 -0
  26. microsoft_agents/hosting/dialogs/dialog_extensions.py +201 -0
  27. microsoft_agents/hosting/dialogs/dialog_manager.py +189 -0
  28. microsoft_agents/hosting/dialogs/dialog_manager_result.py +17 -0
  29. microsoft_agents/hosting/dialogs/dialog_set.py +174 -0
  30. microsoft_agents/hosting/dialogs/dialog_state.py +20 -0
  31. microsoft_agents/hosting/dialogs/memory/__init__.py +24 -0
  32. microsoft_agents/hosting/dialogs/memory/component_memory_scopes_base.py +14 -0
  33. microsoft_agents/hosting/dialogs/memory/component_path_resolvers_base.py +15 -0
  34. microsoft_agents/hosting/dialogs/memory/dialog_path.py +33 -0
  35. microsoft_agents/hosting/dialogs/memory/dialog_state_manager.py +563 -0
  36. microsoft_agents/hosting/dialogs/memory/dialog_state_manager_configuration.py +11 -0
  37. microsoft_agents/hosting/dialogs/memory/path_resolver_base.py +8 -0
  38. microsoft_agents/hosting/dialogs/memory/path_resolvers/__init__.py +19 -0
  39. microsoft_agents/hosting/dialogs/memory/path_resolvers/alias_path_resolver.py +53 -0
  40. microsoft_agents/hosting/dialogs/memory/path_resolvers/at_at_path_resolver.py +9 -0
  41. microsoft_agents/hosting/dialogs/memory/path_resolvers/at_path_resolver.py +44 -0
  42. microsoft_agents/hosting/dialogs/memory/path_resolvers/dollar_path_resolver.py +9 -0
  43. microsoft_agents/hosting/dialogs/memory/path_resolvers/hash_path_resolver.py +9 -0
  44. microsoft_agents/hosting/dialogs/memory/path_resolvers/percent_path_resolver.py +9 -0
  45. microsoft_agents/hosting/dialogs/memory/scope_path.py +38 -0
  46. microsoft_agents/hosting/dialogs/memory/scopes/__init__.py +31 -0
  47. microsoft_agents/hosting/dialogs/memory/scopes/bot_state_memory_scope.py +66 -0
  48. microsoft_agents/hosting/dialogs/memory/scopes/class_memory_scope.py +64 -0
  49. microsoft_agents/hosting/dialogs/memory/scopes/conversation_memory_scope.py +12 -0
  50. microsoft_agents/hosting/dialogs/memory/scopes/dialog_class_memory_scope.py +52 -0
  51. microsoft_agents/hosting/dialogs/memory/scopes/dialog_context_memory_scope.py +68 -0
  52. microsoft_agents/hosting/dialogs/memory/scopes/dialog_memory_scope.py +75 -0
  53. microsoft_agents/hosting/dialogs/memory/scopes/memory_scope.py +91 -0
  54. microsoft_agents/hosting/dialogs/memory/scopes/settings_memory_scope.py +38 -0
  55. microsoft_agents/hosting/dialogs/memory/scopes/this_memory_scope.py +36 -0
  56. microsoft_agents/hosting/dialogs/memory/scopes/turn_memory_scope.py +86 -0
  57. microsoft_agents/hosting/dialogs/memory/scopes/user_memory_scope.py +12 -0
  58. microsoft_agents/hosting/dialogs/models/__init__.py +15 -0
  59. microsoft_agents/hosting/dialogs/models/dialog_event.py +13 -0
  60. microsoft_agents/hosting/dialogs/models/dialog_events.py +12 -0
  61. microsoft_agents/hosting/dialogs/models/dialog_instance.py +28 -0
  62. microsoft_agents/hosting/dialogs/models/dialog_reason.py +34 -0
  63. microsoft_agents/hosting/dialogs/models/dialog_turn_result.py +17 -0
  64. microsoft_agents/hosting/dialogs/models/dialog_turn_status.py +26 -0
  65. microsoft_agents/hosting/dialogs/object_path.py +315 -0
  66. microsoft_agents/hosting/dialogs/persisted_state.py +22 -0
  67. microsoft_agents/hosting/dialogs/persisted_state_keys.py +8 -0
  68. microsoft_agents/hosting/dialogs/prompts/__init__.py +41 -0
  69. microsoft_agents/hosting/dialogs/prompts/activity_prompt.py +203 -0
  70. microsoft_agents/hosting/dialogs/prompts/attachment_prompt.py +87 -0
  71. microsoft_agents/hosting/dialogs/prompts/choice_prompt.py +156 -0
  72. microsoft_agents/hosting/dialogs/prompts/confirm_prompt.py +161 -0
  73. microsoft_agents/hosting/dialogs/prompts/datetime_prompt.py +90 -0
  74. microsoft_agents/hosting/dialogs/prompts/datetime_resolution.py +16 -0
  75. microsoft_agents/hosting/dialogs/prompts/number_prompt.py +81 -0
  76. microsoft_agents/hosting/dialogs/prompts/oauth_prompt.py +569 -0
  77. microsoft_agents/hosting/dialogs/prompts/oauth_prompt_settings.py +43 -0
  78. microsoft_agents/hosting/dialogs/prompts/prompt.py +224 -0
  79. microsoft_agents/hosting/dialogs/prompts/prompt_culture_models.py +222 -0
  80. microsoft_agents/hosting/dialogs/prompts/prompt_options.py +42 -0
  81. microsoft_agents/hosting/dialogs/prompts/prompt_recognizer_result.py +11 -0
  82. microsoft_agents/hosting/dialogs/prompts/prompt_validator.py +0 -0
  83. microsoft_agents/hosting/dialogs/prompts/prompt_validator_context.py +44 -0
  84. microsoft_agents/hosting/dialogs/prompts/text_prompt.py +82 -0
  85. microsoft_agents/hosting/dialogs/waterfall_dialog.py +266 -0
  86. microsoft_agents/hosting/dialogs/waterfall_step_context.py +109 -0
  87. microsoft_agents_hosting_dialogs-0.10.0.dev2.dist-info/METADATA +87 -0
  88. microsoft_agents_hosting_dialogs-0.10.0.dev2.dist-info/RECORD +91 -0
  89. microsoft_agents_hosting_dialogs-0.10.0.dev2.dist-info/WHEEL +5 -0
  90. microsoft_agents_hosting_dialogs-0.10.0.dev2.dist-info/licenses/LICENSE +21 -0
  91. microsoft_agents_hosting_dialogs-0.10.0.dev2.dist-info/top_level.txt +1 -0
@@ -0,0 +1,148 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+
4
+ from collections.abc import Iterable
5
+
6
+ from recognizers_number import NumberModel, NumberRecognizer, OrdinalModel
7
+ from recognizers_text import Culture
8
+
9
+ from typing import cast
10
+
11
+
12
+ from .models.choice import Choice
13
+ from .find import Find
14
+ from .models.find_choices_options import FindChoicesOptions
15
+ from .models.found_choice import FoundChoice
16
+ from .models.model_result import ModelResult
17
+
18
+
19
+ class ChoiceRecognizers:
20
+ """Contains methods for matching user input against a list of choices."""
21
+
22
+ @staticmethod
23
+ def recognize_choices(
24
+ utterance: str,
25
+ choices: Iterable[str | Choice],
26
+ options: FindChoicesOptions | None = None,
27
+ ) -> list[ModelResult]:
28
+ """
29
+ Matches user input against a list of choices.
30
+
31
+ This is layered above the `Find.find_choices()` function, and adds logic to let the user specify
32
+ their choice by index (they can say "one" to pick `choice[0]`) or ordinal position
33
+ (they can say "the second one" to pick `choice[1]`.)
34
+ The user's utterance is recognized in the following order:
35
+
36
+ - By name using `find_choices()`
37
+ - By 1's based ordinal position.
38
+ - By 1's based index position.
39
+
40
+ Parameters
41
+ -----------
42
+
43
+ utterance: The input.
44
+
45
+ choices: The list of choices.
46
+
47
+ options: (Optional) Options to control the recognition strategy.
48
+
49
+ Returns
50
+ --------
51
+ A list of found choices, sorted by most relevant first.
52
+ """
53
+ if utterance is None:
54
+ utterance = ""
55
+
56
+ # Normalize list of choices
57
+ choices_list = [
58
+ Choice(value=choice) if isinstance(choice, str) else choice
59
+ for choice in choices
60
+ ]
61
+
62
+ # Try finding choices by text search first
63
+ # - We only want to use a single strategy for returning results to avoid issues where utterances
64
+ # like the "the third one" or "the red one" or "the first division book" would miss-recognize as
65
+ # a numerical index or ordinal as well.
66
+ locale = options.locale if (options and options.locale) else Culture.English
67
+ matched = Find.find_choices(utterance, choices_list, options)
68
+ if not matched:
69
+ matches = []
70
+
71
+ if not options or options.recognize_ordinals:
72
+ # Next try finding by ordinal
73
+ matches = ChoiceRecognizers._recognize_ordinal(utterance, locale)
74
+ for match in matches:
75
+ ChoiceRecognizers._match_choice_by_index(
76
+ choices_list, matched, match
77
+ )
78
+
79
+ if not matches and (not options or options.recognize_numbers):
80
+ # Then try by numerical index
81
+ matches = ChoiceRecognizers._recognize_number(utterance, locale)
82
+ for match in matches:
83
+ ChoiceRecognizers._match_choice_by_index(
84
+ choices_list, matched, match
85
+ )
86
+
87
+ # Sort any found matches by their position within the utterance.
88
+ # - The results from find_choices() are already properly sorted so we just need this
89
+ # for ordinal & numerical lookups.
90
+ matched = sorted(matched, key=lambda model_result: model_result.start)
91
+
92
+ return matched
93
+
94
+ @staticmethod
95
+ def _recognize_ordinal(utterance: str, culture: str) -> list[ModelResult]:
96
+ model: OrdinalModel = cast(
97
+ OrdinalModel, NumberRecognizer(culture).get_ordinal_model(culture)
98
+ )
99
+
100
+ return list(
101
+ map(ChoiceRecognizers._found_choice_constructor, model.parse(utterance)) # type: ignore[arg-type]
102
+ )
103
+
104
+ @staticmethod
105
+ def _match_choice_by_index(
106
+ choices: list[Choice], matched: list[ModelResult], match: ModelResult
107
+ ):
108
+ try:
109
+ index: int = int(match.resolution.value) - 1
110
+ if 0 <= index < len(choices):
111
+ choice = choices[index]
112
+
113
+ matched.append(
114
+ ModelResult(
115
+ start=match.start,
116
+ end=match.end,
117
+ type_name="choice",
118
+ text=match.text,
119
+ resolution=FoundChoice(
120
+ value=choice.value, index=index, score=1.0
121
+ ),
122
+ )
123
+ )
124
+ except:
125
+ # noop here, as in dotnet/node repos
126
+ pass
127
+
128
+ @staticmethod
129
+ def _recognize_number(utterance: str, culture: str) -> list[ModelResult]:
130
+ model: NumberModel = cast(
131
+ NumberModel, NumberRecognizer(culture).get_number_model(culture)
132
+ )
133
+
134
+ return list(
135
+ map(ChoiceRecognizers._found_choice_constructor, model.parse(utterance)) # type: ignore[arg-type]
136
+ )
137
+
138
+ @staticmethod
139
+ def _found_choice_constructor(value_model: ModelResult) -> ModelResult:
140
+ return ModelResult(
141
+ start=value_model.start,
142
+ end=value_model.end,
143
+ type_name="choice",
144
+ text=value_model.text,
145
+ resolution=FoundChoice(
146
+ value=value_model.resolution["value"], index=0, score=1.0
147
+ ),
148
+ )
@@ -0,0 +1,242 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+
4
+ from typing import Callable
5
+ from collections.abc import Iterable
6
+
7
+ from .models.choice import Choice
8
+ from .models.find_choices_options import FindChoicesOptions, FindValuesOptions
9
+ from .models.found_choice import FoundChoice
10
+ from .models.found_value import FoundValue
11
+ from .models.model_result import ModelResult
12
+ from .models.sorted_value import SortedValue
13
+ from .models.token import Token
14
+ from .tokenizer import Tokenizer
15
+
16
+
17
+ class Find:
18
+ """Contains methods for matching user input against a list of choices"""
19
+
20
+ @staticmethod
21
+ def find_choices(
22
+ utterance: str,
23
+ choices: Iterable[str | Choice],
24
+ options: FindChoicesOptions | None = None,
25
+ ) -> list[ModelResult]:
26
+ """Matches user input against a list of choices"""
27
+
28
+ if not choices:
29
+ raise TypeError("Find: choices cannot be None.")
30
+
31
+ opt = options or FindChoicesOptions()
32
+
33
+ # Normalize list of choices
34
+ choices_list = [
35
+ Choice(value=choice) if isinstance(choice, str) else choice
36
+ for choice in choices
37
+ ]
38
+
39
+ # Build up full list of synonyms to search over.
40
+ # - Each entry in the list contains the index of the choice it belongs to which will later be
41
+ # used to map the search results back to their choice.
42
+ synonyms: list[SortedValue] = []
43
+
44
+ for index, choice in enumerate(choices_list):
45
+ if not opt.no_value:
46
+ synonyms.append(SortedValue(value=choice.value, index=index))
47
+
48
+ if choice.action and choice.action.title and not opt.no_action:
49
+ synonyms.append(SortedValue(value=choice.action.title, index=index))
50
+
51
+ if choice.synonyms is not None:
52
+ for synonym in choice.synonyms:
53
+ synonyms.append(SortedValue(value=synonym, index=index))
54
+
55
+ def found_choice_constructor(value_model: ModelResult) -> ModelResult:
56
+ choice = choices_list[value_model.resolution.index]
57
+
58
+ return ModelResult(
59
+ start=value_model.start,
60
+ end=value_model.end,
61
+ type_name="choice",
62
+ text=value_model.text,
63
+ resolution=FoundChoice(
64
+ value=choice.value,
65
+ index=value_model.resolution.index,
66
+ score=value_model.resolution.score,
67
+ synonym=value_model.resolution.value,
68
+ ),
69
+ )
70
+
71
+ # Find synonyms in utterance and map back to their choices_list
72
+ return list(
73
+ map(found_choice_constructor, Find.find_values(utterance, synonyms, opt))
74
+ )
75
+
76
+ @staticmethod
77
+ def find_values(
78
+ utterance: str,
79
+ values: list[SortedValue],
80
+ options: FindValuesOptions | None = None,
81
+ ) -> list[ModelResult]:
82
+ # Sort values in descending order by length, so that the longest value is searchd over first.
83
+ sorted_values = sorted(
84
+ values, key=lambda sorted_val: len(sorted_val.value), reverse=True
85
+ )
86
+
87
+ # Search for each value within the utterance.
88
+ matches: list[ModelResult] = []
89
+ opt = options if options else FindValuesOptions()
90
+ tokenizer: Callable[[str, str | None], list[Token]] = (
91
+ opt.tokenizer if opt.tokenizer else Tokenizer.default_tokenizer
92
+ )
93
+ tokens = tokenizer(utterance, opt.locale)
94
+ max_distance = (
95
+ opt.max_token_distance if opt.max_token_distance is not None else 2
96
+ )
97
+
98
+ for entry in sorted_values:
99
+ # Find all matches for a value
100
+ # - To match "last one" in "the last time I chose the last one" we need
101
+ # to re-search the string starting from the end of the previous match.
102
+ # - The start & end position returned for the match are token positions.
103
+ start_pos = 0
104
+ searched_tokens = tokenizer(entry.value.strip(), opt.locale)
105
+
106
+ while start_pos < len(tokens):
107
+ match: ModelResult | None = Find._match_value(
108
+ tokens,
109
+ max_distance,
110
+ opt,
111
+ entry.index,
112
+ entry.value,
113
+ searched_tokens,
114
+ start_pos,
115
+ )
116
+
117
+ if match is not None:
118
+ start_pos = match.end + 1
119
+ matches.append(match)
120
+ else:
121
+ break
122
+
123
+ # Sort matches by score descending
124
+ sorted_matches = sorted(
125
+ matches,
126
+ key=lambda model_result: model_result.resolution.score,
127
+ reverse=True,
128
+ )
129
+
130
+ # Filter out duplicate matching indexes and overlapping characters
131
+ # - The start & end positions are token positions and need to be translated to
132
+ # character positions before returning. We also need to populate the "text"
133
+ # field as well.
134
+ results: list[ModelResult] = []
135
+ found_indexes = set()
136
+ used_tokens = set()
137
+
138
+ for match in sorted_matches:
139
+ # Apply filters.
140
+ add = match.resolution.index not in found_indexes
141
+
142
+ for i in range(match.start, match.end + 1):
143
+ if i in used_tokens:
144
+ add = False
145
+ break
146
+
147
+ # Add to results
148
+ if add:
149
+ # Update filter info
150
+ found_indexes.add(match.resolution.index)
151
+
152
+ for i in range(match.start, match.end + 1):
153
+ used_tokens.add(i)
154
+
155
+ # Translate start & end and populate text field
156
+ match.start = tokens[match.start].start
157
+ match.end = tokens[match.end].end
158
+ match.text = utterance[match.start : match.end + 1]
159
+ results.append(match)
160
+
161
+ # Return the results sorted by position in the utterance
162
+ return sorted(results, key=lambda model_result: model_result.start)
163
+
164
+ @staticmethod
165
+ def _match_value(
166
+ source_tokens: list[Token],
167
+ max_distance: int,
168
+ options: FindValuesOptions,
169
+ index: int,
170
+ value: str,
171
+ searched_tokens: list[Token],
172
+ start_pos: int,
173
+ ) -> ModelResult | None:
174
+ # Match value to utterance and calculate total deviation.
175
+ # - The tokens are matched in order so "second last" will match in
176
+ # "the second from last one" but not in "the last from the second one".
177
+ # - The total deviation is a count of the number of tokens skipped in the
178
+ # match so for the example above the number of tokens matched would be
179
+ # 2 and the total deviation would be 1.
180
+ matched = 0
181
+ total_deviation = 0
182
+ start = -1
183
+ end = -1
184
+
185
+ for token in searched_tokens:
186
+ # Find the position of the token in the utterance.
187
+ pos = Find._index_of_token(source_tokens, token, start_pos)
188
+ if pos >= 0:
189
+ # Calculate the distance between the current token's position and the previous token's distance.
190
+ distance = pos - start_pos if matched > 0 else 0
191
+ if distance <= max_distance:
192
+ # Update count of tokens matched and move start pointer to search for next token
193
+ # after the current token
194
+ matched += 1
195
+ total_deviation += distance
196
+ start_pos = pos + 1
197
+
198
+ # Update start & end position that will track the span of the utterance that's matched.
199
+ if start < 0:
200
+ start = pos
201
+
202
+ end = pos
203
+
204
+ # Calculate score and format result
205
+ # - The start & end positions and the results text field will be corrected by the caller.
206
+ result: ModelResult | None = None
207
+
208
+ if matched > 0 and (
209
+ matched == len(searched_tokens) or options.allow_partial_matches
210
+ ):
211
+ # Percentage of tokens matched. If matching "second last" in
212
+ # "the second form last one" the completeness would be 1.0 since
213
+ # all tokens were found.
214
+ completeness = matched / len(searched_tokens)
215
+
216
+ # Accuracy of the match. The accuracy is reduced by additional tokens
217
+ # occuring in the value that weren't in the utterance. So an utterance
218
+ # of "second last" matched against a value of "second from last" would
219
+ # result in an accuracy of 0.5.
220
+ accuracy = float(matched) / (matched + total_deviation)
221
+
222
+ # The final score is simply the compeleteness multiplied by the accuracy.
223
+ score = completeness * accuracy
224
+
225
+ # Format result
226
+ result = ModelResult(
227
+ text="",
228
+ start=start,
229
+ end=end,
230
+ type_name="value",
231
+ resolution=FoundValue(value=value, index=index, score=score),
232
+ )
233
+
234
+ return result
235
+
236
+ @staticmethod
237
+ def _index_of_token(tokens: list[Token], token: Token, start_pos: int) -> int:
238
+ for i in range(start_pos, len(tokens)):
239
+ if tokens[i].normalized == token.normalized:
240
+ return i
241
+
242
+ return -1
@@ -0,0 +1,23 @@
1
+ from .choice_factory_options import ChoiceFactoryOptions
2
+ from .choice import Choice
3
+ from .find_choices_options import FindChoicesOptions
4
+ from .find_values_options import FindValuesOptions
5
+ from .found_choice import FoundChoice
6
+ from .found_value import FoundValue
7
+ from .list_style import ListStyle
8
+ from .model_result import ModelResult
9
+ from .sorted_value import SortedValue
10
+ from .token import Token
11
+
12
+ __all__ = [
13
+ "ChoiceFactoryOptions",
14
+ "Choice",
15
+ "FindChoicesOptions",
16
+ "FindValuesOptions",
17
+ "FoundChoice",
18
+ "FoundValue",
19
+ "ListStyle",
20
+ "ModelResult",
21
+ "SortedValue",
22
+ "Token",
23
+ ]
@@ -0,0 +1,14 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+
4
+ from dataclasses import dataclass, field
5
+
6
+ from microsoft_agents.activity import CardAction
7
+
8
+
9
+ @dataclass
10
+ class Choice:
11
+
12
+ value: str = ""
13
+ action: CardAction | None = None
14
+ synonyms: list[str] = field(default_factory=list)
@@ -0,0 +1,13 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+
4
+ from dataclasses import dataclass
5
+
6
+
7
+ @dataclass
8
+ class ChoiceFactoryOptions:
9
+
10
+ inline_separator: str | None = None
11
+ inline_or: str | None = None
12
+ inline_or_more: str | None = None
13
+ include_numbers: bool = True
@@ -0,0 +1,28 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+
4
+ from dataclasses import dataclass
5
+
6
+ from .find_values_options import FindValuesOptions
7
+
8
+
9
+ @dataclass
10
+ class FindChoicesOptions(FindValuesOptions):
11
+ """Contains options to control how input is matched against a list of choices
12
+
13
+ no_value: If `True`, the choices `value` field will NOT be search over. Defaults to `False`.
14
+
15
+ no_action: If `True`, the choices `action.title` field will NOT be searched over.
16
+ Defaults to `False`.
17
+
18
+ recognize_numbers: Indicates whether the recognizer should check for Numbers using the
19
+ NumberRecognizer's NumberModel.
20
+
21
+ recognize_ordinals: Indicates whether the recognizer should check for Ordinal Numbers using
22
+ the NumberRecognizer's OrdinalModel.
23
+ """
24
+
25
+ no_value: bool = False
26
+ no_action: bool = False
27
+ recognize_numbers: bool = True
28
+ recognize_ordinals: bool = True
@@ -0,0 +1,31 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+
4
+ from collections.abc import Iterable
5
+ from dataclasses import dataclass
6
+ from typing import Callable
7
+
8
+ from .token import Token
9
+
10
+
11
+ @dataclass
12
+ class FindValuesOptions:
13
+ """Contains search options, used to control how choices are recognized in a user's utterance.
14
+
15
+ allow_partial_matches: (Optional) If `True`, then only some of the tokens in a value need to exist to be considered
16
+ a match. The default value is `False`.
17
+
18
+ locale: (Optional) locale/culture code of the utterance. Default is `en-US`.
19
+
20
+ max_token_distance: (Optional) maximum tokens allowed between two matched tokens in the utterance. So with
21
+ a max distance of 2 the value "second last" would match the utterance "second from the last"
22
+ but it wouldn't match "Wait a second. That's not the last one is it?".
23
+ The default value is "2".
24
+
25
+ tokenizer: (Optional) Tokenizer to use when parsing the utterance and values being recognized.
26
+ """
27
+
28
+ allow_partial_matches: bool = False
29
+ locale: str = "en-US"
30
+ max_token_distance: int = 2
31
+ tokenizer: Callable[[str, str | None], list[Token]] | None = None
@@ -0,0 +1,22 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+
4
+ from dataclasses import dataclass
5
+
6
+
7
+ @dataclass
8
+ class FoundChoice:
9
+ """Represents a result from matching user input against a list of choices.
10
+
11
+
12
+ value: The value of the choice that was matched.
13
+ index: The index of the choice that was matched.
14
+ score: The accuracy with which the synonym matched the specified portion of the utterance.
15
+ A value of 1.0 would indicate a perfect match.
16
+ synonym: The synonym that was matched in case of a synonym match.
17
+ """
18
+
19
+ value: str
20
+ index: int
21
+ score: float
22
+ synonym: str | None = None
@@ -0,0 +1,20 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+
4
+ from dataclasses import dataclass
5
+
6
+
7
+ @dataclass
8
+ class FoundValue:
9
+ """Represents a result from matching user input against a list of choices
10
+
11
+
12
+ value: The value that was matched.
13
+ index: The index of the value that was matched.
14
+ score: The accuracy with which the synonym matched the specified portion of the utterance.
15
+ A value of 1.0 would indicate a perfect match.
16
+ """
17
+
18
+ value: str
19
+ index: int
20
+ score: float
@@ -0,0 +1,15 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+
4
+ from enum import Enum
5
+
6
+
7
+ class ListStyle(int, Enum):
8
+ """Defines the style of list to present choices to the user."""
9
+
10
+ none = 0
11
+ auto = 1
12
+ in_line = 2
13
+ list_style = 3
14
+ suggested_action = 4
15
+ hero_card = 5
@@ -0,0 +1,16 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+
4
+ from dataclasses import dataclass
5
+ from typing import Any
6
+
7
+
8
+ @dataclass
9
+ class ModelResult:
10
+ """Contains recognition result information."""
11
+
12
+ text: str
13
+ start: int
14
+ end: int
15
+ type_name: str
16
+ resolution: Any
@@ -0,0 +1,16 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+
4
+ from dataclasses import dataclass
5
+
6
+
7
+ @dataclass
8
+ class SortedValue:
9
+ """A value that can be sorted and still refer to its original position with a source array.
10
+
11
+ value: the value that will be sorted.
12
+ index: the value's original position within its unsorted array.
13
+ """
14
+
15
+ value: str
16
+ index: int
@@ -0,0 +1,20 @@
1
+ # Copyright (c) Microsoft Corporation. All rights reserved.
2
+ # Licensed under the MIT License.
3
+
4
+ from dataclasses import dataclass
5
+
6
+
7
+ @dataclass
8
+ class Token:
9
+ """Represents an individual token, such as a word in an input string.
10
+
11
+ start: The index of the first character of the token within the outer input string.
12
+ end: The index of the last character of the token within the outer input string.
13
+ text: The original text of the token.
14
+ normalized: A normalized version of the token. This can include things like lower casing or stemming.
15
+ """
16
+
17
+ start: int
18
+ end: int
19
+ text: str
20
+ normalized: str | None