unique_toolkit 1.45.0__py3-none-any.whl → 1.45.2__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.
@@ -1,18 +1,101 @@
1
+ from __future__ import annotations
2
+
1
3
  import mimetypes
2
4
  from enum import StrEnum
5
+ from pathlib import Path
3
6
 
4
7
 
5
8
  class FileMimeType(StrEnum):
6
9
  PDF = "application/pdf"
7
10
  DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
8
11
  DOC = "application/msword"
12
+ # TODO: clean up duplicates and make the monolith compatible with this.
9
13
  XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
14
+ MSEXCEL = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
10
15
  XLS = "application/vnd.ms-excel"
16
+ EXCEL = "application/vnd.ms-excel"
17
+ PPT = "application/vnd.ms-powerpoint"
11
18
  PPTX = "application/vnd.openxmlformats-officedocument.presentationml.presentation"
19
+ MSPPT = "application/vnd.openxmlformats-officedocument.presentationml.presentation"
12
20
  CSV = "text/csv"
13
21
  HTML = "text/html"
14
22
  MD = "text/markdown"
15
23
  TXT = "text/plain"
24
+ JSON = "application/json"
25
+
26
+ @classmethod
27
+ def get_mime_from_file_path(cls, filepath: Path) -> "FileMimeType | None":
28
+ mime_type, _ = mimetypes.guess_type(filepath)
29
+ if mime_type is None:
30
+ return None
31
+ try:
32
+ return cls(mime_type)
33
+ except ValueError:
34
+ return None
35
+
36
+ @classmethod
37
+ def is_docx_mime(cls, filepath: Path) -> bool:
38
+ mime_type = cls.get_mime_from_file_path(filepath)
39
+ return mime_type in {cls.DOCX, cls.DOC}
40
+
41
+ @classmethod
42
+ def is_pdf_mime(cls, filepath: Path) -> bool:
43
+ mime_type = cls.get_mime_from_file_path(filepath)
44
+ return mime_type == cls.PDF
45
+
46
+ @classmethod
47
+ def is_xlsx_mime(cls, filepath: Path) -> bool:
48
+ mime_type = cls.get_mime_from_file_path(filepath)
49
+ return mime_type in {cls.XLSX, cls.XLS, cls.MSEXCEL, cls.EXCEL}
50
+
51
+ @classmethod
52
+ def is_pptx_mime(cls, filepath: Path) -> bool:
53
+ mime_type = cls.get_mime_from_file_path(filepath)
54
+ return mime_type in {cls.PPTX, cls.PPT, cls.MSPPT}
55
+
56
+ @classmethod
57
+ def is_json_mime(cls, filepath: Path) -> bool:
58
+ mime_type = cls.get_mime_from_file_path(filepath)
59
+ return mime_type == cls.JSON
60
+
61
+ @classmethod
62
+ def is_valid_mime(cls, filepath: Path, valid_mimes: list[FileMimeType]) -> bool:
63
+ mime_type = cls.get_mime_from_file_path(filepath)
64
+ return mime_type in valid_mimes
65
+
66
+
67
+ def get_common_name(extension: FileMimeType) -> str:
68
+ match extension:
69
+ case FileMimeType.DOCX | FileMimeType.DOC:
70
+ return "docx"
71
+ case (
72
+ FileMimeType.XLSX
73
+ | FileMimeType.XLS
74
+ | FileMimeType.MSEXCEL
75
+ | FileMimeType.EXCEL
76
+ ):
77
+ return "excel"
78
+ case FileMimeType.PPT | FileMimeType.PPTX | FileMimeType.MSPPT:
79
+ return "powerpoint"
80
+ case FileMimeType.PDF:
81
+ return "pdf"
82
+ case FileMimeType.JSON:
83
+ return "json"
84
+ case FileMimeType.CSV:
85
+ return "csv"
86
+ case FileMimeType.TXT:
87
+ return "text"
88
+ case FileMimeType.MD:
89
+ return "markdown"
90
+ case FileMimeType.HTML:
91
+ return "html"
92
+ case _:
93
+ return "unknown"
94
+
95
+
96
+ def get_file_extensions(mimes: list[FileMimeType]) -> list[str]:
97
+ types = [mimetypes.guess_extension(mime) for mime in mimes]
98
+ return [t for t in types if t]
16
99
 
17
100
 
18
101
  class ImageMimeType(StrEnum):
@@ -10,6 +10,7 @@ from pydantic import RootModel
10
10
  from unique_toolkit._common.token.token_counting import (
11
11
  num_tokens_per_language_model_message,
12
12
  )
13
+ from unique_toolkit._common.utils import files as FileUtils
13
14
  from unique_toolkit.app import ChatEventUserMessage
14
15
  from unique_toolkit.chat.schemas import ChatMessage
15
16
  from unique_toolkit.chat.schemas import ChatMessageRole as ChatRole
@@ -29,29 +30,6 @@ map_chat_llm_message_role = {
29
30
  }
30
31
 
31
32
 
32
- class ImageMimeType(StrEnum):
33
- JPEG = "image/jpeg"
34
- PNG = "image/png"
35
- GIF = "image/gif"
36
- BMP = "image/bmp"
37
- WEBP = "image/webp"
38
- TIFF = "image/tiff"
39
- SVG = "image/svg+xml"
40
-
41
-
42
- class FileMimeType(StrEnum):
43
- PDF = "application/pdf"
44
- DOCX = "application/vnd.openxmlformats-officedocument.wordprocessingml.document"
45
- DOC = "application/msword"
46
- XLSX = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
47
- XLS = "application/vnd.ms-excel"
48
- PPTX = "application/vnd.openxmlformats-officedocument.presentationml.presentation"
49
- CSV = "text/csv"
50
- HTML = "text/html"
51
- MD = "text/markdown"
52
- TXT = "text/plain"
53
-
54
-
55
33
  class ChatMessageWithContents(ChatMessage):
56
34
  contents: list[Content] = []
57
35
 
@@ -93,24 +71,6 @@ class ChatHistoryWithContent(RootModel):
93
71
  return self.root[item]
94
72
 
95
73
 
96
- def is_image_content(filename: str) -> bool:
97
- mimetype, _ = mimetypes.guess_type(filename)
98
-
99
- if not mimetype:
100
- return False
101
-
102
- return mimetype in ImageMimeType.__members__.values()
103
-
104
-
105
- def is_file_content(filename: str) -> bool:
106
- mimetype, _ = mimetypes.guess_type(filename)
107
-
108
- if not mimetype:
109
- return False
110
-
111
- return mimetype in FileMimeType.__members__.values()
112
-
113
-
114
74
  def get_chat_history_with_contents(
115
75
  user_message: ChatEventUserMessage,
116
76
  chat_id: str,
@@ -152,7 +112,7 @@ def download_encoded_images(
152
112
  ) -> list[str]:
153
113
  base64_encoded_images = []
154
114
  for im in contents:
155
- if is_image_content(im.key):
115
+ if FileUtils.is_image_content(im.key):
156
116
  try:
157
117
  file_bytes = content_service.download_content_to_bytes(
158
118
  content_id=im.id,
@@ -224,8 +184,12 @@ def get_full_history_with_contents(
224
184
  text = ""
225
185
 
226
186
  if len(c.contents) > 0:
227
- file_contents = [co for co in c.contents if is_file_content(co.key)]
228
- image_contents = [co for co in c.contents if is_image_content(co.key)]
187
+ file_contents = [
188
+ co for co in c.contents if FileUtils.is_file_content(co.key)
189
+ ]
190
+ image_contents = [
191
+ co for co in c.contents if FileUtils.is_image_content(co.key)
192
+ ]
229
193
 
230
194
  content = (
231
195
  text
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unique_toolkit
3
- Version: 1.45.0
3
+ Version: 1.45.2
4
4
  Summary:
5
5
  License: Proprietary
6
6
  Author: Cedric Klinkert
@@ -125,6 +125,12 @@ All notable changes to this project will be documented in this file.
125
125
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
126
126
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
127
127
 
128
+ ## [1.45.2] - 2026-01-26
129
+ - Make FileMimeType backwards compatible with legacy extensions
130
+
131
+ ## [1.45.1] - 2026-01-26
132
+ - Add FileMimeType utility helpers
133
+
128
134
  ## [1.45.0] - 2026-01-23
129
135
  - Remove unused code execution options from config
130
136
 
@@ -55,7 +55,7 @@ unique_toolkit/_common/tests/test_string_utilities.py,sha256=J2HYZ1fniOfJWI149wl
55
55
  unique_toolkit/_common/token/image_token_counting.py,sha256=VpFfZyY0GIH27q_Wy4YNjk2algqvbCtJyzuuROoFQPw,2189
56
56
  unique_toolkit/_common/token/token_counting.py,sha256=gM4B_aUqKqEPvmStFNcvCWNMNNNNKbVaywBDxlbgIps,7121
57
57
  unique_toolkit/_common/utils/__init__.py,sha256=qHrEy-3zkbFPdGFriRscPbGKuQfOuPi3O7tE5Zw5VHY,37
58
- unique_toolkit/_common/utils/files.py,sha256=97PkhXDUMXFEhje5HzWMMlLvZj49A6jOifqFRIrzu5M,1102
58
+ unique_toolkit/_common/utils/files.py,sha256=GLfbk-gcLIh5J1nlWMa2hWx0IDzrCvSNDTfjMa9ktbU,3905
59
59
  unique_toolkit/_common/utils/image/encode.py,sha256=IJhtTcIT_azhiDsPp15oYs2LPze2l-sGlZrJASHrDVI,658
60
60
  unique_toolkit/_common/utils/jinja/helpers.py,sha256=UQWj0hFMtnuUFYDJ8NKbEblvYE8DrWX1o7fKQU3H9IQ,262
61
61
  unique_toolkit/_common/utils/jinja/render.py,sha256=J5UBIWoljl-Us7SjZIap9wewcLTzpXjQpOgas_YTf3Y,482
@@ -86,7 +86,7 @@ unique_toolkit/agentic/evaluation/tests/test_context_relevancy_service.py,sha256
86
86
  unique_toolkit/agentic/evaluation/tests/test_output_parser.py,sha256=RN_HcBbU6qy_e_PoYyUFcjWnp3ymJ6-gLj6TgEOupAI,3107
87
87
  unique_toolkit/agentic/feature_flags/__init__.py,sha256=LhE2cHoa9AYBOR7TjiIToOn46sttm9paKcrzE7gnDPM,149
88
88
  unique_toolkit/agentic/feature_flags/feature_flags.py,sha256=4jPH0GGGt5-tQ6PJWNpMBIlYzNrQIIqBLx8W02lwxD0,1140
89
- unique_toolkit/agentic/history_manager/history_construction_with_contents.py,sha256=kzxpVzTtQqL8TjdIvOy7gkRVxD4BsOMyimECryg7vdc,9060
89
+ unique_toolkit/agentic/history_manager/history_construction_with_contents.py,sha256=TwamOOnYTYZMQdY1mAzj6_MZOe3T5RsjFDarT1tCtYo,8150
90
90
  unique_toolkit/agentic/history_manager/history_manager.py,sha256=7V7_173XkAjc8otBACF0G3dbqRs34FSlURbBPrE95Wk,9537
91
91
  unique_toolkit/agentic/history_manager/loop_token_reducer.py,sha256=3c-uonDovtanEJUpAO4zlA4-n9MS_Ws_V0Yb6G7hPM0,20172
92
92
  unique_toolkit/agentic/history_manager/utils.py,sha256=VIn_UmcR3jHtpux0qp5lQQzczgAm8XYSeQiPo87jC3A,3143
@@ -244,7 +244,7 @@ unique_toolkit/short_term_memory/service.py,sha256=5PeVBu1ZCAfyDb2HLVvlmqSbyzBBu
244
244
  unique_toolkit/smart_rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
245
245
  unique_toolkit/smart_rules/compile.py,sha256=Ozhh70qCn2yOzRWr9d8WmJeTo7AQurwd3tStgBMPFLA,1246
246
246
  unique_toolkit/test_utilities/events.py,sha256=_mwV2bs5iLjxS1ynDCjaIq-gjjKhXYCK-iy3dRfvO3g,6410
247
- unique_toolkit-1.45.0.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
248
- unique_toolkit-1.45.0.dist-info/METADATA,sha256=wfMYzHsUT5U9jNgqX5uNaIFj_rE_1TfL-iySEmB6l-U,48751
249
- unique_toolkit-1.45.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
250
- unique_toolkit-1.45.0.dist-info/RECORD,,
247
+ unique_toolkit-1.45.2.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
248
+ unique_toolkit-1.45.2.dist-info/METADATA,sha256=WeKaLthzSrgmcOWbNRtK0VrZrwVEBtOhgM1Id-P5Els,48902
249
+ unique_toolkit-1.45.2.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
250
+ unique_toolkit-1.45.2.dist-info/RECORD,,