unique_toolkit 0.9.1__py3-none-any.whl → 1.1.0__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.
@@ -0,0 +1 @@
1
+
@@ -42,7 +42,8 @@ def get_sse_client(
42
42
 
43
43
 
44
44
  def get_event_generator(
45
- unique_settings: UniqueSettings, event_type: type[T]
45
+ unique_settings: UniqueSettings,
46
+ event_type: type[T],
46
47
  ) -> Generator[T, None, None]:
47
48
  """
48
49
  Generator that yields only events of the specified type from an SSE stream.
@@ -68,7 +69,9 @@ def get_event_generator(
68
69
  try:
69
70
  payload = json.loads(sse_event.data)
70
71
  parsed_event = event_type.model_validate(payload)
71
- if parsed_event is None:
72
+ if parsed_event is None or parsed_event.filter_event(
73
+ filter_options=unique_settings.chat_event_filter_options
74
+ ):
72
75
  continue
73
76
 
74
77
  yield parsed_event
@@ -1,14 +1,18 @@
1
1
  import json
2
2
  from enum import StrEnum
3
3
  from pathlib import Path
4
- from typing import Any, Optional
4
+ from typing import Any, Generic, Optional, TypeVar, override
5
5
 
6
6
  from humps import camelize
7
7
  from pydantic import BaseModel, ConfigDict, Field, field_validator
8
+ from pydantic_settings import BaseSettings
8
9
  from typing_extensions import deprecated
9
10
 
11
+ from unique_toolkit.app.unique_settings import UniqueChatEventFilterOptions
10
12
  from unique_toolkit.smart_rules.compile import UniqueQL, parse_uniqueql
11
13
 
14
+ FilterOptionsT = TypeVar("FilterOptionsT", bound=BaseSettings)
15
+
12
16
  # set config to convert camelCase to snake_case
13
17
  model_config = ConfigDict(
14
18
  alias_generator=camelize,
@@ -30,7 +34,7 @@ class EventName(StrEnum):
30
34
  MAGIC_TABLE_UPDATE_CELL = "unique.magic-table.update-cell"
31
35
 
32
36
 
33
- class BaseEvent(BaseModel):
37
+ class BaseEvent(BaseModel, Generic[FilterOptionsT]):
34
38
  model_config = model_config
35
39
 
36
40
  id: str
@@ -46,6 +50,10 @@ class BaseEvent(BaseModel):
46
50
  data = json.load(f)
47
51
  return cls.model_validate(data)
48
52
 
53
+ def filter_event(self, *, filter_options: FilterOptionsT | None = None) -> bool:
54
+ """Determine if event should be filtered out and be neglected."""
55
+ return False
56
+
49
57
 
50
58
  ###
51
59
  # MCP schemas
@@ -242,6 +250,28 @@ class ChatEvent(BaseEvent):
242
250
  "assistant": {"id": self.payload.assistant_id},
243
251
  }
244
252
 
253
+ @override
254
+ def filter_event(
255
+ self, *, filter_options: UniqueChatEventFilterOptions | None = None
256
+ ) -> bool:
257
+ # Empty string evals to False
258
+ if filter_options is None:
259
+ return False
260
+
261
+ if (
262
+ filter_options.assistant_ids
263
+ and self.payload.assistant_id not in filter_options.assistant_ids
264
+ ):
265
+ return True
266
+
267
+ if (
268
+ filter_options.references_in_code
269
+ and self.payload.name not in filter_options.references_in_code
270
+ ):
271
+ return True
272
+
273
+ return super().filter_event(filter_options=filter_options)
274
+
245
275
 
246
276
  @deprecated(
247
277
  """Use the more specific `ChatEvent` instead that has the same properties. \
@@ -49,6 +49,7 @@ class UniqueApp(BaseSettings):
49
49
  deprecated="Use UniqueApi.base_url instead",
50
50
  )
51
51
  endpoint: str = Field(default="dummy")
52
+
52
53
  endpoint_secret: SecretStr = Field(default=SecretStr("dummy_secret"))
53
54
 
54
55
  @model_validator(mode="after")
@@ -159,6 +160,29 @@ class UniqueAuth(BaseSettings):
159
160
  return warn_about_defaults(self)
160
161
 
161
162
 
163
+ class UniqueChatEventFilterOptions(BaseSettings):
164
+ # Empty string evals to False
165
+ assistant_ids: list[str] = Field(
166
+ default=[],
167
+ description="The assistant ids (space) to filter by. Default is all assistants.",
168
+ )
169
+ references_in_code: list[str] = Field(
170
+ default=[],
171
+ description="The module (reference) names in code to filter by. Default is all modules.",
172
+ )
173
+
174
+ model_config = SettingsConfigDict(
175
+ env_prefix="unique_chat_event_filter_options_",
176
+ env_file_encoding="utf-8",
177
+ case_sensitive=False,
178
+ extra="ignore",
179
+ )
180
+
181
+ @model_validator(mode="after")
182
+ def _warn_about_defaults(self) -> Self:
183
+ return warn_about_defaults(self)
184
+
185
+
162
186
  class EnvFileNotFoundError(FileNotFoundError):
163
187
  """Raised when no environment file can be found in any of the expected locations."""
164
188
 
@@ -169,11 +193,14 @@ class UniqueSettings:
169
193
  auth: UniqueAuth,
170
194
  app: UniqueApp,
171
195
  api: UniqueApi,
196
+ *,
197
+ chat_event_filter_options: UniqueChatEventFilterOptions | None = None,
172
198
  env_file: Path | None = None,
173
199
  ):
174
200
  self.app = app
175
201
  self.auth = auth
176
202
  self.api = api
203
+ self.chat_event_filter_options = chat_event_filter_options
177
204
  self._env_file: Path | None = (
178
205
  env_file if (env_file and env_file.exists()) else None
179
206
  )
@@ -220,7 +247,10 @@ class UniqueSettings:
220
247
  )
221
248
 
222
249
  @classmethod
223
- def from_env(cls, env_file: Path | None = None) -> "UniqueSettings":
250
+ def from_env(
251
+ cls,
252
+ env_file: Path | None = None,
253
+ ) -> "UniqueSettings":
224
254
  """Initialize settings from environment variables and/or env file.
225
255
 
226
256
  Args:
@@ -241,7 +271,14 @@ class UniqueSettings:
241
271
  auth = UniqueAuth(_env_file=env_file_str) # type: ignore[call-arg]
242
272
  app = UniqueApp(_env_file=env_file_str) # type: ignore[call-arg]
243
273
  api = UniqueApi(_env_file=env_file_str) # type: ignore[call-arg]
244
- return cls(auth=auth, app=app, api=api, env_file=env_file)
274
+ event_filter_options = UniqueChatEventFilterOptions(_env_file=env_file_str) # type: ignore[call-arg]
275
+ return cls(
276
+ auth=auth,
277
+ app=app,
278
+ api=api,
279
+ chat_event_filter_options=event_filter_options,
280
+ env_file=env_file,
281
+ )
245
282
 
246
283
  @classmethod
247
284
  def from_env_auto(cls, filename: str = "unique.env") -> "UniqueSettings":
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unique_toolkit
3
- Version: 0.9.1
3
+ Version: 1.1.0
4
4
  Summary:
5
5
  License: Proprietary
6
6
  Author: Cedric Klinkert
@@ -118,6 +118,12 @@ All notable changes to this project will be documented in this file.
118
118
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
119
119
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
120
120
 
121
+ ## [1.1.0] - 2025-09-18
122
+ - Enable chat event filtering in SSE event generator via env variables
123
+
124
+ ## [1.0.0] - 2025-09-18
125
+ - Bump toolkit version to allow for both patch and minor updates
126
+
121
127
  ## [0.9.1] - 2025-09-17
122
128
  - update to python 3.12 due to security
123
129
 
@@ -19,6 +19,7 @@ unique_toolkit/_common/utils/structured_output/schema.py,sha256=Tp7kDYcmKtnUhcuR
19
19
  unique_toolkit/_common/utils/write_configuration.py,sha256=fzvr4C-XBL3OSM3Od9TbqIxeeDS9_d9CLEyTq6DDknY,1409
20
20
  unique_toolkit/_common/validate_required_values.py,sha256=Y_M1ub9gIKP9qZ45F6Zq3ZHtuIqhmOjl8Z2Vd3avg8w,588
21
21
  unique_toolkit/_common/validators.py,sha256=aZwbMho7XszN7lT5RtemaiXgC0WJ4u40oeVgsNGhF4U,2803
22
+ unique_toolkit/agentic/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
22
23
  unique_toolkit/agentic/debug_info_manager/debug_info_manager.py,sha256=8u3_oxcln7y2zOsfiGh5YOm1zYAlV5QxZ5YAsbEJG0c,584
23
24
  unique_toolkit/agentic/evaluation/config.py,sha256=ywHIrJs5SFdKr1WXfrofWuFfzb0iPQw8iZDpq5oEug4,953
24
25
  unique_toolkit/agentic/evaluation/context_relevancy/prompts.py,sha256=EdHFUOB581yVxcOL8482KUv_LzaRjuiem71EF8udYMc,1331
@@ -71,13 +72,13 @@ unique_toolkit/agentic/tools/utils/source_handling/schema.py,sha256=l4B6kA6grbL-
71
72
  unique_toolkit/agentic/tools/utils/source_handling/source_formatting.py,sha256=uZ0QXqrPWgId3ZA67dvjHQ6xrW491LK1xxx_sVJmFHg,9160
72
73
  unique_toolkit/agentic/tools/utils/source_handling/tests/test_source_formatting.py,sha256=EA8iVvb3L91OFk2XMbGcFuhe2etqm3Sx9QCYDGiOSOM,6995
73
74
  unique_toolkit/app/__init__.py,sha256=ETxYDpEizg_PKmi4JPX_P76ySq-us-xypfAIdKQ1QZU,1284
74
- unique_toolkit/app/dev_util.py,sha256=1C5aGUQnyO8Kot9i35PPFl4B32Oj9eK22WKTP_BrfwY,5063
75
+ unique_toolkit/app/dev_util.py,sha256=BmrVpZ86_X3NCd9irNPvT5VFL9-7tF7muZeaCL53j4M,5185
75
76
  unique_toolkit/app/init_logging.py,sha256=Sh26SRxOj8i8dzobKhYha2lLrkrMTHfB1V4jR3h23gQ,678
76
77
  unique_toolkit/app/init_sdk.py,sha256=5_oDoETr6akwYyBCb0ivTdMNu3SVgPSkrXcDS6ELyY8,2269
77
78
  unique_toolkit/app/performance/async_tasks.py,sha256=H0l3OAcosLwNHZ8d2pd-Di4wHIXfclEvagi5kfqLFPA,1941
78
79
  unique_toolkit/app/performance/async_wrapper.py,sha256=yVVcRDkcdyfjsxro-N29SBvi-7773wnfDplef6-y8xw,1077
79
- unique_toolkit/app/schemas.py,sha256=xHdzMyZ_cgCzxCqzCJYwOCAYWkaQ9zIyZsRhDgSQnEA,8088
80
- unique_toolkit/app/unique_settings.py,sha256=vtbtfpxGrK1ZsyVUGiGulG35d2euSSFxE3qj0eiXKVA,10381
80
+ unique_toolkit/app/schemas.py,sha256=UE1UaL_N2o48O-mLb_rF3Sp9MrVkfdDE6f_dm7WTOO4,9137
81
+ unique_toolkit/app/unique_settings.py,sha256=JNU0LrlldVx1GUeSS0Mr1tqT67934KWU2OeVWkNUu28,11510
81
82
  unique_toolkit/app/verification.py,sha256=GxFFwcJMy25fCA_Xe89wKW7bgqOu8PAs5y8QpHF0GSc,3861
82
83
  unique_toolkit/chat/__init__.py,sha256=LRs2G-JTVuci4lbtHTkVUiNcZcSR6uqqfnAyo7af6nY,619
83
84
  unique_toolkit/chat/constants.py,sha256=05kq6zjqUVB2d6_P7s-90nbljpB3ryxwCI-CAz0r2O4,83
@@ -123,7 +124,7 @@ unique_toolkit/short_term_memory/schemas.py,sha256=OhfcXyF6ACdwIXW45sKzjtZX_gkcJ
123
124
  unique_toolkit/short_term_memory/service.py,sha256=5PeVBu1ZCAfyDb2HLVvlmqSbyzBBuE9sI2o9Aajqjxg,8884
124
125
  unique_toolkit/smart_rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
125
126
  unique_toolkit/smart_rules/compile.py,sha256=cxWjb2dxEI2HGsakKdVCkSNi7VK9mr08w5sDcFCQyWI,9553
126
- unique_toolkit-0.9.1.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
127
- unique_toolkit-0.9.1.dist-info/METADATA,sha256=preWvo_48KQIFiYTSJtgXfHx4ZrJMe-NipmzyL6s2nQ,32215
128
- unique_toolkit-0.9.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
129
- unique_toolkit-0.9.1.dist-info/RECORD,,
127
+ unique_toolkit-1.1.0.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
128
+ unique_toolkit-1.1.0.dist-info/METADATA,sha256=upTGYXRy0kIWh32G1W37OCkFFW68zXXWJoI44OqnCM8,32401
129
+ unique_toolkit-1.1.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
130
+ unique_toolkit-1.1.0.dist-info/RECORD,,