unique_toolkit 0.7.24__py3-none-any.whl → 0.7.26__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.
@@ -2,9 +2,11 @@ from enum import StrEnum
2
2
  from typing import Any, Optional
3
3
 
4
4
  from humps import camelize
5
- from pydantic import BaseModel, ConfigDict, Field
5
+ from pydantic import BaseModel, ConfigDict, Field, field_validator
6
6
  from typing_extensions import deprecated
7
7
 
8
+ from unique_toolkit.smart_rules.compile import UniqueQL, parse_uniqueql
9
+
8
10
  # set config to convert camelCase to snake_case
9
11
  model_config = ConfigDict(
10
12
  alias_generator=camelize,
@@ -95,15 +97,31 @@ class ChatEventPayload(BaseModel):
95
97
  assistant_id: str
96
98
  user_message: ChatEventUserMessage
97
99
  assistant_message: ChatEventAssistantMessage
98
- text: Optional[str] = None
99
- additional_parameters: Optional[ChatEventAdditionalParameters] = None
100
- user_metadata: Optional[dict[str, Any]] = None
101
- tool_choices: Optional[list[str]] = Field(
102
- default=[],
100
+ text: str | None = None
101
+ additional_parameters: ChatEventAdditionalParameters | None = None
102
+ user_metadata: dict[str, Any] | None = Field(
103
+ default_factory=dict,
104
+ )
105
+ tool_choices: list[str] = Field(
106
+ default_factory=list,
103
107
  description="A list containing the tool names the user has chosen to be activated.",
104
108
  )
105
- tool_parameters: Optional[dict[str, Any]] = None
106
- metadata_filter: Optional[dict[str, Any]] = None
109
+ tool_parameters: dict[str, Any] = Field(
110
+ default_factory=dict,
111
+ description="Parameters extracted from module selection function calling the tool.",
112
+ )
113
+ metadata_filter: dict[str, Any] = Field(
114
+ default_factory=dict,
115
+ description="Metadata filter compiled after module selection function calling and scope rules.",
116
+ )
117
+ raw_scope_rules: UniqueQL | None = Field(
118
+ default=None,
119
+ description="Raw UniqueQL rule that can be compiled to a metadata filter.",
120
+ )
121
+
122
+ @field_validator("raw_scope_rules", mode="before")
123
+ def validate_scope_rules(cls, value: dict[str, Any]) -> UniqueQL:
124
+ return parse_uniqueql(value)
107
125
 
108
126
 
109
127
  @deprecated("""Use `ChatEventPayload` instead.
@@ -3,6 +3,7 @@ import os
3
3
  import re
4
4
  import tempfile
5
5
  from pathlib import Path
6
+ from typing import Any
6
7
 
7
8
  import requests
8
9
  import unique_sdk
@@ -214,7 +215,7 @@ def upload_content_from_bytes(
214
215
  chat_id: str | None = None,
215
216
  skip_ingestion: bool = False,
216
217
  ingestion_config: unique_sdk.Content.IngestionConfig | None = None,
217
- metadata: dict[str, any] | None = None,
218
+ metadata: dict[str, Any] | None = None,
218
219
  ):
219
220
  """
220
221
  Uploads content to the knowledge base.
@@ -229,7 +230,7 @@ def upload_content_from_bytes(
229
230
  chat_id (str | None): The chat ID. Defaults to None.
230
231
  skip_ingestion (bool): Whether to skip ingestion. Defaults to False.
231
232
  ingestion_config (unique_sdk.Content.IngestionConfig | None): The ingestion configuration. Defaults to None.
232
- metadata ( dict[str, any] | None): The metadata for the content. Defaults to None.
233
+ metadata ( dict[str, Any] | None): The metadata for the content. Defaults to None.
233
234
 
234
235
  Returns:
235
236
  Content: The uploaded content.
@@ -263,7 +264,7 @@ def upload_content(
263
264
  chat_id: str | None = None,
264
265
  skip_ingestion: bool = False,
265
266
  ingestion_config: unique_sdk.Content.IngestionConfig | None = None,
266
- metadata: dict[str, any] | None = None,
267
+ metadata: dict[str, Any] | None = None,
267
268
  ):
268
269
  """
269
270
  Uploads content to the knowledge base.
@@ -278,7 +279,7 @@ def upload_content(
278
279
  chat_id (str | None): The chat ID. Defaults to None.
279
280
  skip_ingestion (bool): Whether to skip ingestion. Defaults to False.
280
281
  ingestion_config (unique_sdk.Content.IngestionConfig | None): The ingestion configuration. Defaults to None.
281
- metadata ( dict[str, any] | None): The metadata for the content. Defaults to None.
282
+ metadata ( dict[str, Any] | None): The metadata for the content. Defaults to None.
282
283
 
283
284
  Returns:
284
285
  Content: The uploaded content.
@@ -312,7 +313,7 @@ def _trigger_upload_content(
312
313
  chat_id: str | None = None,
313
314
  skip_ingestion: bool = False,
314
315
  ingestion_config: unique_sdk.Content.IngestionConfig | None = None,
315
- metadata: dict[str, any] | None = None,
316
+ metadata: dict[str, Any] | None = None,
316
317
  ):
317
318
  """
318
319
  Uploads content to the knowledge base.
@@ -327,7 +328,7 @@ def _trigger_upload_content(
327
328
  chat_id (str | None): The chat ID. Defaults to None.
328
329
  skip_ingestion (bool): Whether to skip ingestion. Defaults to False.
329
330
  ingestion_config (unique_sdk.Content.IngestionConfig | None): The ingestion configuration. Defaults to None.
330
- metadata (dict[str, any] | None): The metadata for the content. Defaults to None.
331
+ metadata (dict[str, Any] | None): The metadata for the content. Defaults to None.
331
332
 
332
333
  Returns:
333
334
  Content: The uploaded content.
@@ -1,6 +1,6 @@
1
1
  from datetime import datetime
2
2
  from enum import StrEnum
3
- from typing import Optional
3
+ from typing import Any, Optional
4
4
 
5
5
  from humps import camelize
6
6
  from pydantic import BaseModel, ConfigDict, Field
@@ -54,7 +54,7 @@ class Content(BaseModel):
54
54
  read_url: str | None = None
55
55
  created_at: datetime | None = None
56
56
  updated_at: datetime | None = None
57
- metadata: dict[str, any] | None = None
57
+ metadata: dict[str, Any] | None = None
58
58
  ingestion_config: dict | None = None
59
59
 
60
60
 
@@ -1,5 +1,6 @@
1
1
  import logging
2
2
  from pathlib import Path
3
+ from typing import Any
3
4
 
4
5
  import unique_sdk
5
6
  from requests import Response
@@ -408,7 +409,7 @@ class ContentService:
408
409
  chat_id: str | None = None,
409
410
  skip_ingestion: bool = False,
410
411
  ingestion_config: unique_sdk.Content.IngestionConfig | None = None,
411
- metadata: dict[str, any] | None = None,
412
+ metadata: dict[str, Any] | None = None,
412
413
  ):
413
414
  """
414
415
  Uploads content to the knowledge base.
@@ -421,7 +422,7 @@ class ContentService:
421
422
  chat_id (str | None): The chat ID. Defaults to None.
422
423
  skip_ingestion (bool): Whether to skip ingestion. Defaults to False.
423
424
  ingestion_config (unique_sdk.Content.IngestionConfig | None): The ingestion configuration. Defaults to None.
424
- metadata (dict[str, any] | None): The metadata to associate with the content. Defaults to None.
425
+ metadata (dict[str, Any] | None): The metadata to associate with the content. Defaults to None.
425
426
 
426
427
  Returns:
427
428
  Content: The uploaded content.
@@ -23,6 +23,8 @@ class LanguageModelName(StrEnum):
23
23
  AZURE_o3_MINI_2025_0131 = "AZURE_o3_MINI_2025_0131"
24
24
  AZURE_GPT_45_PREVIEW_2025_0227 = "AZURE_GPT_45_PREVIEW_2025_0227"
25
25
  AZURE_GPT_41_2025_0414 = "AZURE_GPT_41_2025_0414"
26
+ AZURE_GPT_41_MINI_2025_0414 = "AZURE_GPT_41_MINI_2025_0414"
27
+ AZURE_GPT_41_NANO_2025_0414 = "AZURE_GPT_41_NANO_2025_0414"
26
28
  AZURE_o3_2025_0416 = "AZURE_o3_2025_0416"
27
29
  AZURE_o4_MINI_2025_0416 = "AZURE_o4_MINI_2025_0416"
28
30
  ANTHROPIC_CLAUDE_3_7_SONNET = "litellm:anthropic-claude-3-7-sonnet"
@@ -378,6 +380,42 @@ class LanguageModelInfo(BaseModel):
378
380
  info_cutoff_at=date(2024, 5, 31),
379
381
  published_at=date(2025, 4, 14),
380
382
  )
383
+ case LanguageModelName.AZURE_GPT_41_MINI_2025_0414:
384
+ return cls(
385
+ name=model_name,
386
+ capabilities=[
387
+ ModelCapabilities.STRUCTURED_OUTPUT,
388
+ ModelCapabilities.FUNCTION_CALLING,
389
+ ModelCapabilities.STREAMING,
390
+ ModelCapabilities.VISION,
391
+ ],
392
+ provider=LanguageModelProvider.AZURE,
393
+ version="2025-04-14",
394
+ encoder_name=EncoderName.O200K_BASE,
395
+ token_limits=LanguageModelTokenLimits(
396
+ token_limit_input=1_047_576, token_limit_output=32_768
397
+ ),
398
+ info_cutoff_at=date(2024, 5, 31),
399
+ published_at=date(2025, 4, 14),
400
+ )
401
+ case LanguageModelName.AZURE_GPT_41_NANO_2025_0414:
402
+ return cls(
403
+ name=model_name,
404
+ capabilities=[
405
+ ModelCapabilities.STRUCTURED_OUTPUT,
406
+ ModelCapabilities.FUNCTION_CALLING,
407
+ ModelCapabilities.STREAMING,
408
+ ModelCapabilities.VISION,
409
+ ],
410
+ provider=LanguageModelProvider.AZURE,
411
+ version="2025-04-14",
412
+ encoder_name=EncoderName.O200K_BASE,
413
+ token_limits=LanguageModelTokenLimits(
414
+ token_limit_input=1_047_576, token_limit_output=32_768
415
+ ),
416
+ info_cutoff_at=date(2024, 5, 31),
417
+ published_at=date(2025, 4, 14),
418
+ )
381
419
  case LanguageModelName.ANTHROPIC_CLAUDE_3_7_SONNET:
382
420
  return cls(
383
421
  name=model_name,
File without changes
@@ -0,0 +1,301 @@
1
+ import re
2
+ from datetime import datetime, timedelta, timezone
3
+ from enum import Enum
4
+ from typing import Any, Dict, List, Self, Union
5
+
6
+ from pydantic import AliasChoices, BaseModel, Field
7
+ from pydantic.config import ConfigDict
8
+
9
+
10
+ class Operator(str, Enum):
11
+ EQUALS = "equals"
12
+ NOT_EQUALS = "notEquals"
13
+ GREATER_THAN = "greaterThan"
14
+ GREATER_THAN_OR_EQUAL = "greaterThanOrEqual"
15
+ LESS_THAN = "lessThan"
16
+ LESS_THAN_OR_EQUAL = "lessThanOrEqual"
17
+ IN = "in"
18
+ NOT_IN = "notIn"
19
+ CONTAINS = "contains"
20
+ NOT_CONTAINS = "notContains"
21
+ IS_NULL = "isNull"
22
+ IS_NOT_NULL = "isNotNull"
23
+ IS_EMPTY = "isEmpty"
24
+ IS_NOT_EMPTY = "isNotEmpty"
25
+ NESTED = "nested"
26
+
27
+
28
+ class BaseStatement(BaseModel):
29
+ model_config: ConfigDict = {"serialize_by_alias": True}
30
+
31
+ def with_variables(
32
+ self,
33
+ user_metadata: Dict[str, Union[str, int, bool]],
34
+ tool_parameters: Dict[str, Union[str, int, bool]],
35
+ ) -> Self:
36
+ return self._fill_in_variables(user_metadata, tool_parameters)
37
+
38
+ def is_compiled(self) -> bool:
39
+ # Serialize the object to json string
40
+ json_str = self.model_dump_json()
41
+ # Check if the json string has <T> or <T+> or <T-> or <toolParameters or <userMetadata
42
+ return (
43
+ "<T>" in json_str
44
+ or "<T+" in json_str
45
+ or "<T-" in json_str
46
+ or "<toolParameters" in json_str
47
+ or "<userMetadata" in json_str
48
+ )
49
+
50
+ def _fill_in_variables(
51
+ self,
52
+ user_metadata: Dict[str, Union[str, int, bool]],
53
+ tool_parameters: Dict[str, Union[str, int, bool]],
54
+ ) -> Self:
55
+ return self.model_copy()
56
+
57
+
58
+ class Statement(BaseStatement):
59
+ operator: Operator
60
+ value: Union[str, int, bool, list[str], "AndStatement", "OrStatement"]
61
+ path: List[str] = Field(default_factory=list)
62
+
63
+ def _fill_in_variables(
64
+ self,
65
+ user_metadata: Dict[str, Union[str, int, bool]],
66
+ tool_parameters: Dict[str, Union[str, int, bool]],
67
+ ) -> Self:
68
+ new_stmt = self.model_copy()
69
+ new_stmt.value = eval_operator(self, user_metadata, tool_parameters)
70
+ return new_stmt
71
+
72
+
73
+ class AndStatement(BaseStatement):
74
+ and_list: List[Union["Statement", "AndStatement", "OrStatement"]] = Field(
75
+ alias="and", validation_alias=AliasChoices("and", "and_list")
76
+ )
77
+
78
+ def _fill_in_variables(
79
+ self,
80
+ user_metadata: Dict[str, Union[str, int, bool]],
81
+ tool_parameters: Dict[str, Union[str, int, bool]],
82
+ ) -> Self:
83
+ new_stmt = self.model_copy()
84
+ new_stmt.and_list = [
85
+ sub_query._fill_in_variables(user_metadata, tool_parameters)
86
+ for sub_query in self.and_list
87
+ ]
88
+ return new_stmt
89
+
90
+
91
+ class OrStatement(BaseStatement):
92
+ or_list: List[Union["Statement", "AndStatement", "OrStatement"]] = Field(
93
+ alias="or", validation_alias=AliasChoices("or", "or_list")
94
+ )
95
+
96
+ def _fill_in_variables(
97
+ self,
98
+ user_metadata: Dict[str, Union[str, int, bool]],
99
+ tool_parameters: Dict[str, Union[str, int, bool]],
100
+ ) -> Self:
101
+ new_stmt = self.model_copy()
102
+ new_stmt.or_list = [
103
+ sub_query._fill_in_variables(user_metadata, tool_parameters)
104
+ for sub_query in self.or_list
105
+ ]
106
+ return new_stmt
107
+
108
+
109
+ # Update the forward references
110
+ Statement.model_rebuild()
111
+ AndStatement.model_rebuild()
112
+ OrStatement.model_rebuild()
113
+
114
+
115
+ UniqueQL = Union[Statement, AndStatement, OrStatement]
116
+
117
+
118
+ def is_array_of_strings(value: Any) -> bool:
119
+ return isinstance(value, list) and all(isinstance(item, str) for item in value)
120
+
121
+
122
+ def eval_operator(
123
+ query: Statement,
124
+ user_metadata: Dict[str, Union[str, int, bool]],
125
+ tool_parameters: Dict[str, Union[str, int, bool]],
126
+ ) -> Any:
127
+ if query.operator in [
128
+ Operator.EQUALS,
129
+ Operator.NOT_EQUALS,
130
+ Operator.GREATER_THAN,
131
+ Operator.GREATER_THAN_OR_EQUAL,
132
+ Operator.LESS_THAN,
133
+ Operator.LESS_THAN_OR_EQUAL,
134
+ Operator.CONTAINS,
135
+ Operator.NOT_CONTAINS,
136
+ ]:
137
+ return binary_operator(query.value, user_metadata, tool_parameters)
138
+ elif query.operator in [Operator.IS_NULL, Operator.IS_NOT_NULL]:
139
+ return null_operator(query.value, user_metadata, tool_parameters)
140
+ elif query.operator in [Operator.IS_EMPTY, Operator.IS_NOT_EMPTY]:
141
+ return empty_operator(query.operator, user_metadata, tool_parameters)
142
+ elif query.operator == Operator.NESTED:
143
+ return eval_nested_operator(query.value, user_metadata, tool_parameters)
144
+ elif query.operator in [Operator.IN, Operator.NOT_IN]:
145
+ return array_operator(query.value, user_metadata, tool_parameters)
146
+ else:
147
+ raise ValueError(f"Operator {query.operator} not supported")
148
+
149
+
150
+ def eval_nested_operator(
151
+ value: Any,
152
+ user_metadata: Dict[str, Union[str, int, bool]],
153
+ tool_parameters: Dict[str, Union[str, int, bool]],
154
+ ) -> Union[AndStatement, OrStatement]:
155
+ if not isinstance(value, (AndStatement, OrStatement)):
156
+ raise ValueError("Nested operator must be an AndStatement or OrStatement")
157
+ return value._fill_in_variables(user_metadata, tool_parameters)
158
+
159
+
160
+ def binary_operator(
161
+ value: Any,
162
+ user_metadata: Dict[str, Union[str, int, bool]],
163
+ tool_parameters: Dict[str, Union[str, int, bool]],
164
+ ) -> Any:
165
+ return replace_variables(value, user_metadata, tool_parameters)
166
+
167
+
168
+ def array_operator(
169
+ value: Any,
170
+ user_metadata: Dict[str, Union[str, int, bool]],
171
+ tool_parameters: Dict[str, Union[str, int, bool]],
172
+ ) -> Any:
173
+ if is_array_of_strings(value):
174
+ return [
175
+ replace_variables(item, user_metadata, tool_parameters) for item in value
176
+ ]
177
+ return value
178
+
179
+
180
+ def null_operator(
181
+ value: Any,
182
+ user_metadata: Dict[str, Union[str, int, bool]],
183
+ tool_parameters: Dict[str, Union[str, int, bool]],
184
+ ) -> Any:
185
+ return value # do nothing for now. No variables to replace
186
+
187
+
188
+ def empty_operator(
189
+ operator: Operator,
190
+ user_metadata: Dict[str, Union[str, int, bool]],
191
+ tool_parameters: Dict[str, Union[str, int, bool]],
192
+ ) -> Any:
193
+ """Handle IS_EMPTY and IS_NOT_EMPTY operators."""
194
+ if operator == Operator.IS_EMPTY:
195
+ return ""
196
+ elif operator == Operator.IS_NOT_EMPTY:
197
+ return "not_empty"
198
+ return None
199
+
200
+
201
+ def calculate_current_date() -> str:
202
+ """Calculate current date in UTC with seconds precision."""
203
+ return datetime.now(timezone.utc).isoformat(timespec="seconds")
204
+
205
+
206
+ def calculate_earlier_date(input_str: str) -> str:
207
+ match = re.search(r"<T-(\d+)>", input_str)
208
+ if not match:
209
+ return calculate_current_date() # Return current date if no match
210
+ days = int(match.group(1))
211
+ return (datetime.now(timezone.utc) - timedelta(days=days)).isoformat(
212
+ timespec="seconds"
213
+ )
214
+
215
+
216
+ def calculate_later_date(input_str: str) -> str:
217
+ match = re.search(r"<T\+(\d+)>", input_str) # Note: escaped + in regex
218
+ if not match:
219
+ return calculate_current_date() # Return current date if no match
220
+ days = int(match.group(1))
221
+ return (datetime.now(timezone.utc) + timedelta(days=days)).isoformat(
222
+ timespec="seconds"
223
+ )
224
+
225
+
226
+ def replace_variables(
227
+ value: Any,
228
+ user_metadata: Dict[str, Union[str, int, bool]],
229
+ tool_parameters: Dict[str, Union[str, int, bool]],
230
+ ) -> Any:
231
+ if isinstance(value, str):
232
+ if "||" in value:
233
+ return get_fallback_values(value, user_metadata, tool_parameters)
234
+ elif value == "<T>":
235
+ return calculate_current_date()
236
+ elif "<T-" in value:
237
+ return calculate_earlier_date(value)
238
+ elif "<T+" in value:
239
+ return calculate_later_date(value)
240
+
241
+ value = replace_tool_parameters_patterns(value, tool_parameters)
242
+ value = replace_user_metadata_patterns(value, user_metadata)
243
+
244
+ if value == "":
245
+ return value
246
+ try:
247
+ return int(value)
248
+ except ValueError:
249
+ if value.lower() in ["true", "false"]:
250
+ return value.lower() == "true"
251
+ return value
252
+ return value
253
+
254
+
255
+ def replace_tool_parameters_patterns(
256
+ value: str, tool_parameters: Dict[str, Union[str, int, bool]]
257
+ ) -> str:
258
+ def replace_match(match):
259
+ param_name = match.group(1)
260
+ return str(tool_parameters.get(param_name, ""))
261
+
262
+ return re.sub(r"<toolParameters\.(\w+)>", replace_match, value)
263
+
264
+
265
+ def replace_user_metadata_patterns(
266
+ value: str, user_metadata: Dict[str, Union[str, int, bool]]
267
+ ) -> str:
268
+ def replace_match(match):
269
+ param_name = match.group(1)
270
+ return str(user_metadata.get(param_name, ""))
271
+
272
+ return re.sub(r"<userMetadata\.(\w+)>", replace_match, value)
273
+
274
+
275
+ def get_fallback_values(
276
+ value: str,
277
+ user_metadata: Dict[str, Union[str, int, bool]],
278
+ tool_parameters: Dict[str, Union[str, int, bool]],
279
+ ) -> Any:
280
+ values = value.split("||")
281
+ for val in values:
282
+ data = replace_variables(val, user_metadata, tool_parameters)
283
+ if data != "":
284
+ return data
285
+ return values
286
+
287
+
288
+ # Example usage:
289
+ def parse_uniqueql(json_data: Dict[str, Any]) -> UniqueQL:
290
+ if "operator" in json_data:
291
+ return Statement.model_validate(json_data)
292
+ elif "or" in json_data:
293
+ return OrStatement.model_validate(
294
+ {"or": [parse_uniqueql(item) for item in json_data["or"]]}
295
+ )
296
+ elif "and" in json_data:
297
+ return AndStatement.model_validate(
298
+ {"and": [parse_uniqueql(item) for item in json_data["and"]]}
299
+ )
300
+ else:
301
+ raise ValueError("Invalid UniqueQL format")
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unique_toolkit
3
- Version: 0.7.24
3
+ Version: 0.7.26
4
4
  Summary:
5
5
  License: Proprietary
6
6
  Author: Martin Fadler
@@ -111,6 +111,14 @@ All notable changes to this project will be documented in this file.
111
111
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
112
112
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
113
113
 
114
+
115
+ ## [0.7.26] - 2025-06-05
116
+ - Add `scope_rules` to `ChatEventPayload`
117
+ - Added `UniqueQL` compiler and pydantic classes for `UniqueQL`. Note this is functionally equivalent but not identical to `UQLOperator` or `UQLCombinator` in `unique_sdk`.
118
+
119
+ ## [0.7.25] - 2025-06-05
120
+ - Adding models `AZURE_GPT_41_MINI_2025_0414`, `AZURE_GPT_41_NANO_2025_0414`
121
+
114
122
  ## [0.7.24] - 2025-05-30
115
123
  - Adding litellm model `gemini-2-5-flash-preview-05-20`, `anthropic-claude-sonnet-4` and `anthropic-claude-opus-4`
116
124
 
@@ -9,7 +9,7 @@ unique_toolkit/app/init_logging.py,sha256=Sh26SRxOj8i8dzobKhYha2lLrkrMTHfB1V4jR3
9
9
  unique_toolkit/app/init_sdk.py,sha256=Nv4Now4pMfM0AgRhbtatLpm_39rKxn0WmRLwmPhRl-8,1285
10
10
  unique_toolkit/app/performance/async_tasks.py,sha256=H0l3OAcosLwNHZ8d2pd-Di4wHIXfclEvagi5kfqLFPA,1941
11
11
  unique_toolkit/app/performance/async_wrapper.py,sha256=yVVcRDkcdyfjsxro-N29SBvi-7773wnfDplef6-y8xw,1077
12
- unique_toolkit/app/schemas.py,sha256=fNPRQPrpJjYrtkkXPR7sNFjP0AYPZtKe3H1YZkXd2QQ,3275
12
+ unique_toolkit/app/schemas.py,sha256=c2Tu3woqc7gGuHYEspL0mOEyvmqOxTcavbnzZJhSYAs,3969
13
13
  unique_toolkit/app/verification.py,sha256=GxFFwcJMy25fCA_Xe89wKW7bgqOu8PAs5y8QpHF0GSc,3861
14
14
  unique_toolkit/chat/__init__.py,sha256=LRs2G-JTVuci4lbtHTkVUiNcZcSR6uqqfnAyo7af6nY,619
15
15
  unique_toolkit/chat/constants.py,sha256=05kq6zjqUVB2d6_P7s-90nbljpB3ryxwCI-CAz0r2O4,83
@@ -20,9 +20,9 @@ unique_toolkit/chat/state.py,sha256=Cjgwv_2vhDFbV69xxsn7SefhaoIAEqLx3ferdVFCnOg,
20
20
  unique_toolkit/chat/utils.py,sha256=ihm-wQykBWhB4liR3LnwPVPt_qGW6ETq21Mw4HY0THE,854
21
21
  unique_toolkit/content/__init__.py,sha256=EdJg_A_7loEtCQf4cah3QARQreJx6pdz89Rm96YbMVg,940
22
22
  unique_toolkit/content/constants.py,sha256=1iy4Y67xobl5VTnJB6SxSyuoBWbdLl9244xfVMUZi5o,60
23
- unique_toolkit/content/functions.py,sha256=Chf2QcnnWvKvXMF4IUmU-_aUN6nTZIfsbM7ds77olcY,18344
24
- unique_toolkit/content/schemas.py,sha256=28Cj0R9JzJ4s0qR2Sfunr7luwYjMF2I8TepVxt5ZE2o,2446
25
- unique_toolkit/content/service.py,sha256=27awBOsYHdfSxwHM1UzCQLnHuo-M49ej3jpFwBLRflM,19438
23
+ unique_toolkit/content/functions.py,sha256=0ELepm3_sl0SD_SYzvQVQ-jTdrcUqK5mVJZv0nQBuAw,18367
24
+ unique_toolkit/content/schemas.py,sha256=iednldGojmoy9iPZwuIW23BfhWLE9G-fG_qAhxSgr7k,2451
25
+ unique_toolkit/content/service.py,sha256=i7Cf6eQUwBjJntzBfQUvO8JiIjGsNLnsSl9FAwij8xw,19461
26
26
  unique_toolkit/content/utils.py,sha256=GUVPrkZfMoAj4MRoBs5BD_7vSuLZTZx69hyWzYFrI50,7747
27
27
  unique_toolkit/embedding/__init__.py,sha256=uUyzjonPvuDCYsvXCIt7ErQXopLggpzX-MEQd3_e2kE,250
28
28
  unique_toolkit/embedding/constants.py,sha256=Lj8-Lcy1FvuC31PM9Exq7vaFuxQV4pEI1huUMFX-J2M,52
@@ -48,7 +48,7 @@ unique_toolkit/language_model/__init__.py,sha256=lRQyLlbwHbNFf4-0foBU13UGb09lwEe
48
48
  unique_toolkit/language_model/builder.py,sha256=69WCcmkm2rMP2-YEH_EjHiEp6OzwjwCs8VbhjVJaCe0,3168
49
49
  unique_toolkit/language_model/constants.py,sha256=B-topqW0r83dkC_25DeQfnPk3n53qzIHUCBS7YJ0-1U,119
50
50
  unique_toolkit/language_model/functions.py,sha256=koCAfhtkIGSiy8pSdDpIw9xRbwJ20EeLhDQMUXc8KZk,8049
51
- unique_toolkit/language_model/infos.py,sha256=c44oyI0IuYILVmvxndGlKr_OecYz0Zvn8orCAtDv8WQ,28889
51
+ unique_toolkit/language_model/infos.py,sha256=peJ4cSJC__jGLWZoOZGRhoersmkwFmclsXTZi-KqYXc,30723
52
52
  unique_toolkit/language_model/prompt.py,sha256=JSawaLjQg3VR-E2fK8engFyJnNdk21zaO8pPIodzN4Q,3991
53
53
  unique_toolkit/language_model/schemas.py,sha256=DJD2aoMfs2Irnc4rzOrVuV4Fbt84LQAiDGG5rse1dgk,12770
54
54
  unique_toolkit/language_model/service.py,sha256=9LS3ouRNtzqZaKrMFagLZS9gBvNC5e46Ut86YWHBBHY,8470
@@ -59,7 +59,9 @@ unique_toolkit/short_term_memory/constants.py,sha256=698CL6-wjup2MvU19RxSmQk3gX7
59
59
  unique_toolkit/short_term_memory/functions.py,sha256=3WiK-xatY5nh4Dr5zlDUye1k3E6kr41RiscwtTplw5k,4484
60
60
  unique_toolkit/short_term_memory/schemas.py,sha256=OhfcXyF6ACdwIXW45sKzjtZX_gkcJs8FEZXcgQTNenw,1406
61
61
  unique_toolkit/short_term_memory/service.py,sha256=vEKFxP1SScPrFniso492fVthWR1sosdFibhiNF3zRvI,8081
62
- unique_toolkit-0.7.24.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
63
- unique_toolkit-0.7.24.dist-info/METADATA,sha256=s-kBSrSHAM1Qh3g4b_hGvB4EoBFA2jrjlrNu5PzH4I8,23458
64
- unique_toolkit-0.7.24.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
65
- unique_toolkit-0.7.24.dist-info/RECORD,,
62
+ unique_toolkit/smart_rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
63
+ unique_toolkit/smart_rules/compile.py,sha256=44qDrrKD-bKCjjyUep9qa1IwNkneXoQezfFoVm1QToM,9558
64
+ unique_toolkit-0.7.26.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
65
+ unique_toolkit-0.7.26.dist-info/METADATA,sha256=Au6JVHERLYsvDn8yH4tT_K_aB-fK3RhB83-GMIrIjCc,23803
66
+ unique_toolkit-0.7.26.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
67
+ unique_toolkit-0.7.26.dist-info/RECORD,,