unique_toolkit 1.42.7__py3-none-any.whl → 1.42.9__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,6 @@
1
+ from unique_toolkit.agentic.feature_flags.feature_flags import (
2
+ FeatureFlags,
3
+ feature_flags,
4
+ )
5
+
6
+ __all__ = ["FeatureFlags", "feature_flags"]
@@ -0,0 +1,32 @@
1
+ from pydantic import Field
2
+ from pydantic_settings import BaseSettings, SettingsConfigDict
3
+
4
+
5
+ class FeatureFlags(BaseSettings):
6
+ """Feature flags loaded from environment variables.
7
+
8
+ Environment variables are automatically loaded based on field names.
9
+ For example, `feature_flag_enable_new_answers_ui_un_14411` will be loaded from
10
+ `FEATURE_FLAG_ENABLE_NEW_ANSWERS_UI_UN_14411`.
11
+ """
12
+
13
+ feature_flag_enable_new_answers_ui_un_14411: str = Field(
14
+ default="",
15
+ description="Enable new answers UI (UN-14411). Can be 'true' or comma-separated company IDs.",
16
+ )
17
+
18
+ model_config = SettingsConfigDict(
19
+ extra="ignore",
20
+ case_sensitive=False,
21
+ )
22
+
23
+ def is_new_answers_ui_enabled(self, company_id: str | None = None) -> bool:
24
+ """Check if new answers UI is enabled for the given company."""
25
+ value = self.feature_flag_enable_new_answers_ui_un_14411
26
+ return value.lower() == "true" or bool(
27
+ company_id and company_id in [id.strip() for id in value.split(",")]
28
+ )
29
+
30
+
31
+ # Initialize once at module load - import this where needed
32
+ feature_flags = FeatureFlags()
@@ -8,6 +8,7 @@ from collections import defaultdict
8
8
  from logging import getLogger
9
9
 
10
10
  from unique_toolkit.chat.schemas import (
11
+ MessageLog,
11
12
  MessageLogDetails,
12
13
  MessageLogStatus,
13
14
  MessageLogUncitedReferences,
@@ -61,29 +62,23 @@ class MessageStepLogger:
61
62
  self,
62
63
  *,
63
64
  text: str,
65
+ status: MessageLogStatus = MessageLogStatus.COMPLETED,
64
66
  details: MessageLogDetails | None = None,
65
- references: list[ContentReference],
66
- ) -> None:
67
+ references: list[ContentReference] = [],
68
+ ) -> MessageLog | None:
67
69
  """
68
70
  Create a full message log entry with question, hits, and references.
69
-
70
- Args:
71
- text: The prepared string for the message log entry
72
- details: Some formal details about the message log entry
73
- references: List of ContentReference objects to reference
71
+ The created message log entry is returned. If the message log entry is not created, None is returned.
74
72
  """
75
-
76
- # Creating a new message log entry with the found hits.
77
73
  if not self._chat_service._assistant_message_id:
78
74
  _LOGGER.warning(
79
75
  "Assistant message id is not set. Skipping message log entry creation."
80
76
  )
81
77
  return
82
-
83
- _ = self._chat_service.create_message_log(
78
+ return self._chat_service.create_message_log(
84
79
  message_id=self._chat_service._assistant_message_id,
85
80
  text=text,
86
- status=MessageLogStatus.COMPLETED,
81
+ status=status,
87
82
  order=self._get_next_message_order(
88
83
  message_id=self._chat_service._assistant_message_id
89
84
  ),
@@ -91,3 +86,84 @@ class MessageStepLogger:
91
86
  uncited_references=MessageLogUncitedReferences(data=references),
92
87
  references=[],
93
88
  )
89
+
90
+ def update_message_log_entry(
91
+ self,
92
+ *,
93
+ message_log: MessageLog,
94
+ text: str | None = None,
95
+ status: MessageLogStatus,
96
+ details: MessageLogDetails | None = None,
97
+ references: list[ContentReference] = [],
98
+ ) -> MessageLog:
99
+ """
100
+ Update a message log entry with a new status.
101
+ The updated message log entry is returned. If the message log entry is not updated, None is returned.
102
+ """
103
+ if message_log.message_log_id is None:
104
+ _LOGGER.warning(
105
+ "Message log id is not set. Skipping message log entry update."
106
+ )
107
+ return message_log
108
+ return self._chat_service.update_message_log(
109
+ message_log_id=message_log.message_log_id,
110
+ order=message_log.order,
111
+ text=text,
112
+ status=status,
113
+ details=details or MessageLogDetails(data=[]),
114
+ uncited_references=MessageLogUncitedReferences(data=references),
115
+ references=[],
116
+ )
117
+
118
+ def create_or_update_message_log(
119
+ self,
120
+ *,
121
+ active_message_log: MessageLog | None,
122
+ header: str,
123
+ progress_message: str | None = None,
124
+ status: MessageLogStatus = MessageLogStatus.RUNNING,
125
+ details: MessageLogDetails | None = None,
126
+ references: list[ContentReference] | None = [],
127
+ ) -> MessageLog | None:
128
+ """
129
+ Create a new message log entry or update an existing one.
130
+
131
+ This is a convenience method that handles the common pattern of:
132
+ - Creating a new message log if active_message_log is None
133
+ - Updating the existing message log otherwise
134
+
135
+ Args:
136
+ active_message_log: The current active message log, or None if none exists
137
+ header: The header to show in bold (e.g., "Internal Search", "Web Search")
138
+ progress_message: Optional progress message to append after the display name
139
+ status: The status of the message log
140
+ details: Optional message log details
141
+ references: Optional list of content references
142
+
143
+ Returns:
144
+ The created or updated MessageLog, or None if the operation failed
145
+ """
146
+ text = (
147
+ f"**{header}**\n{progress_message}"
148
+ if progress_message is not None
149
+ else f"**{header}**"
150
+ )
151
+
152
+ if references is None:
153
+ references = []
154
+
155
+ if active_message_log is None:
156
+ return self.create_message_log_entry(
157
+ text=text,
158
+ details=details,
159
+ references=references,
160
+ status=status,
161
+ )
162
+ else:
163
+ return self.update_message_log_entry(
164
+ message_log=active_message_log,
165
+ text=text,
166
+ status=status,
167
+ details=details,
168
+ references=references,
169
+ )
@@ -53,6 +53,13 @@ class BaseMetadata(BaseModel):
53
53
  default_factory=dict, description="Additional information for the sheet"
54
54
  )
55
55
 
56
+ @field_validator("additional_sheet_information", mode="before")
57
+ @classmethod
58
+ def normalize_additional_sheet_information(cls, v):
59
+ if v is None:
60
+ return {}
61
+ return v
62
+
56
63
 
57
64
  class RowMetadataEntry(BaseModel):
58
65
  model_config = get_configuration_dict()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unique_toolkit
3
- Version: 1.42.7
3
+ Version: 1.42.9
4
4
  Summary:
5
5
  License: Proprietary
6
6
  Author: Cedric Klinkert
@@ -124,6 +124,13 @@ All notable changes to this project will be documented in this file.
124
124
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
125
125
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
126
126
 
127
+ ## [1.42.9] - 2026-01-11
128
+ - Include feature flag to have message logs compatible with new ChatUI
129
+
130
+ ## [1.42.8] - 2026-01-08
131
+ - Add validator to `BaseMetadata` in case `additional_sheet_information` is empty
132
+ - Add more code snippets to create references and pull file metadata
133
+
127
134
  ## [1.42.7] - 2026-01-08
128
135
  - Add aliases for endpoint secret env var.
129
136
 
@@ -59,6 +59,8 @@ unique_toolkit/agentic/evaluation/output_parser.py,sha256=0FDo8YY_Dc4qlTNeYyQkzn
59
59
  unique_toolkit/agentic/evaluation/schemas.py,sha256=m9JMCUmeqP8KhsJOVEzsz6dRXUe1uKw-bxRDtn5qwvM,3156
60
60
  unique_toolkit/agentic/evaluation/tests/test_context_relevancy_service.py,sha256=4tDxHTApbaTMxN1sNS8WCqj2BweRk6YqZ5_zHP45jto,7977
61
61
  unique_toolkit/agentic/evaluation/tests/test_output_parser.py,sha256=RN_HcBbU6qy_e_PoYyUFcjWnp3ymJ6-gLj6TgEOupAI,3107
62
+ unique_toolkit/agentic/feature_flags/__init__.py,sha256=LhE2cHoa9AYBOR7TjiIToOn46sttm9paKcrzE7gnDPM,149
63
+ unique_toolkit/agentic/feature_flags/feature_flags.py,sha256=4jPH0GGGt5-tQ6PJWNpMBIlYzNrQIIqBLx8W02lwxD0,1140
62
64
  unique_toolkit/agentic/history_manager/history_construction_with_contents.py,sha256=kzxpVzTtQqL8TjdIvOy7gkRVxD4BsOMyimECryg7vdc,9060
63
65
  unique_toolkit/agentic/history_manager/history_manager.py,sha256=7V7_173XkAjc8otBACF0G3dbqRs34FSlURbBPrE95Wk,9537
64
66
  unique_toolkit/agentic/history_manager/loop_token_reducer.py,sha256=3c-uonDovtanEJUpAO4zlA4-n9MS_Ws_V0Yb6G7hPM0,20172
@@ -77,7 +79,7 @@ unique_toolkit/agentic/loop_runner/runners/qwen/__init__.py,sha256=b2zAQIjtPy_BB
77
79
  unique_toolkit/agentic/loop_runner/runners/qwen/helpers.py,sha256=JBnxeYKu8HiUq3VHjnb8XdHCe1c3cJ3OwagckF4UvnU,1763
78
80
  unique_toolkit/agentic/loop_runner/runners/qwen/qwen_runner.py,sha256=7tYfTkNKwxYVn6C1Htya5QEIK2BfWkxCPNkdMoaZGq0,4920
79
81
  unique_toolkit/agentic/message_log_manager/__init__.py,sha256=3-KY_sGkPbNoSnrzwPY0FQIJNnsz4NHXvocXgGRUeuE,169
80
- unique_toolkit/agentic/message_log_manager/service.py,sha256=AiuIq2dKQg9Y8bEYgGcve1X8-WRRdqPZXaZXXLJxfFM,3057
82
+ unique_toolkit/agentic/message_log_manager/service.py,sha256=DeixRsgmyDdWsL-4e12flB9d-Uy7s0X52upPIbTn6vA,5895
81
83
  unique_toolkit/agentic/postprocessor/postprocessor_manager.py,sha256=CoKzVFeLIr1eRP3ZLnmUJ8KNsFLyvK5iuvUilbcGAm0,7662
82
84
  unique_toolkit/agentic/reference_manager/reference_manager.py,sha256=x51CT0D8HHu2LzgXdHGy0leOYpjnsxVbPZ2nc28G9mA,4005
83
85
  unique_toolkit/agentic/responses_api/__init__.py,sha256=9WTO-ef7fGE9Y1QtZJFm8Q_jkwK8Srtl-HWvpAD2Wxs,668
@@ -138,7 +140,7 @@ unique_toolkit/agentic/tools/utils/source_handling/schema.py,sha256=iHBKuks6tUy8
138
140
  unique_toolkit/agentic/tools/utils/source_handling/source_formatting.py,sha256=uZ0QXqrPWgId3ZA67dvjHQ6xrW491LK1xxx_sVJmFHg,9160
139
141
  unique_toolkit/agentic/tools/utils/source_handling/tests/test_source_formatting.py,sha256=EA8iVvb3L91OFk2XMbGcFuhe2etqm3Sx9QCYDGiOSOM,6995
140
142
  unique_toolkit/agentic_table/__init__.py,sha256=smJFstF5qH35RmZfzJUigdsVgUVNOza9KxMbraWrm9E,1411
141
- unique_toolkit/agentic_table/schemas.py,sha256=3lvnOXTwzpaoC4_X69Fj7ayXGa2dPPZhxnCltU2jZa8,9053
143
+ unique_toolkit/agentic_table/schemas.py,sha256=MaG6-LhW5uooAhsyUVOKl8VfCvJ02Drt7dwywJUXKgE,9256
142
144
  unique_toolkit/agentic_table/service.py,sha256=Bgi0B_AT7Mswbud3VI-pNcnc_85xFu4S1dbLttYF7yY,16290
143
145
  unique_toolkit/app/__init__.py,sha256=OaylhLwxeRlsHlcFGSlR5R7oREFsjv9wRdxuVZBYM_8,1371
144
146
  unique_toolkit/app/dev_util.py,sha256=J20peCvrSQKfMGdYPYwCirs3Yq2v_e33GzNBzNKbWN4,5531
@@ -215,7 +217,7 @@ unique_toolkit/short_term_memory/service.py,sha256=5PeVBu1ZCAfyDb2HLVvlmqSbyzBBu
215
217
  unique_toolkit/smart_rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
216
218
  unique_toolkit/smart_rules/compile.py,sha256=Ozhh70qCn2yOzRWr9d8WmJeTo7AQurwd3tStgBMPFLA,1246
217
219
  unique_toolkit/test_utilities/events.py,sha256=_mwV2bs5iLjxS1ynDCjaIq-gjjKhXYCK-iy3dRfvO3g,6410
218
- unique_toolkit-1.42.7.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
219
- unique_toolkit-1.42.7.dist-info/METADATA,sha256=ilOReqP-yar6KvSI-Ew6vNWPv1QO2MdCFXxC62O2CMk,47179
220
- unique_toolkit-1.42.7.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
221
- unique_toolkit-1.42.7.dist-info/RECORD,,
220
+ unique_toolkit-1.42.9.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
221
+ unique_toolkit-1.42.9.dist-info/METADATA,sha256=UlLw100oSlKFi6ycPSH6swuqJZwbzMQebOdbfbookk0,47453
222
+ unique_toolkit-1.42.9.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
223
+ unique_toolkit-1.42.9.dist-info/RECORD,,