unique_toolkit 1.40.0__py3-none-any.whl → 1.41.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.
- unique_toolkit/agentic/evaluation/hallucination/utils.py +54 -7
- unique_toolkit/agentic_table/__init__.py +56 -0
- unique_toolkit/agentic_table/schemas.py +305 -0
- unique_toolkit/agentic_table/service.py +452 -0
- unique_toolkit/app/fast_api_factory.py +15 -7
- {unique_toolkit-1.40.0.dist-info → unique_toolkit-1.41.0.dist-info}/METADATA +8 -1
- {unique_toolkit-1.40.0.dist-info → unique_toolkit-1.41.0.dist-info}/RECORD +9 -6
- {unique_toolkit-1.40.0.dist-info → unique_toolkit-1.41.0.dist-info}/LICENSE +0 -0
- {unique_toolkit-1.40.0.dist-info → unique_toolkit-1.41.0.dist-info}/WHEEL +0 -0
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
+
from enum import StrEnum
|
|
2
3
|
from string import Template
|
|
3
4
|
|
|
4
5
|
from unique_toolkit.agentic.evaluation.config import EvaluationMetricConfig
|
|
@@ -9,6 +10,7 @@ from unique_toolkit.agentic.evaluation.schemas import (
|
|
|
9
10
|
EvaluationMetricName,
|
|
10
11
|
EvaluationMetricResult,
|
|
11
12
|
)
|
|
13
|
+
from unique_toolkit.content import ContentReference
|
|
12
14
|
from unique_toolkit.content.schemas import ContentChunk
|
|
13
15
|
from unique_toolkit.language_model.schemas import (
|
|
14
16
|
LanguageModelMessages,
|
|
@@ -201,13 +203,58 @@ def _get_user_prompt_default(config: EvaluationMetricConfig):
|
|
|
201
203
|
)
|
|
202
204
|
|
|
203
205
|
|
|
206
|
+
class SourceSelectionMode(StrEnum):
|
|
207
|
+
FROM_IDS = "FROM_IDS"
|
|
208
|
+
FROM_ORDER = "FROM_ORDER"
|
|
209
|
+
|
|
210
|
+
|
|
204
211
|
def context_text_from_stream_response(
|
|
205
|
-
response: LanguageModelStreamResponse,
|
|
212
|
+
response: LanguageModelStreamResponse,
|
|
213
|
+
selected_chunks: list[ContentChunk],
|
|
214
|
+
source_selection_mode: SourceSelectionMode = SourceSelectionMode.FROM_IDS,
|
|
206
215
|
):
|
|
207
216
|
response_references = response.message.references
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
217
|
+
match source_selection_mode:
|
|
218
|
+
case SourceSelectionMode.FROM_IDS:
|
|
219
|
+
referenced_chunks = _default_source_selection_mode(
|
|
220
|
+
response_references, selected_chunks
|
|
221
|
+
)
|
|
222
|
+
case SourceSelectionMode.FROM_ORDER:
|
|
223
|
+
referenced_chunks = _from_order_source_selection_mode(
|
|
224
|
+
response_references, selected_chunks
|
|
225
|
+
)
|
|
226
|
+
case _:
|
|
227
|
+
raise ValueError(f"Invalid source selection mode: {source_selection_mode}")
|
|
228
|
+
|
|
229
|
+
return [chunk.text for chunk in referenced_chunks]
|
|
230
|
+
|
|
231
|
+
|
|
232
|
+
def _default_source_selection_mode(
|
|
233
|
+
references: list[ContentReference], selected_chunks: list[ContentChunk]
|
|
234
|
+
):
|
|
235
|
+
reference_ids = {reference.source_id for reference in references}
|
|
236
|
+
|
|
237
|
+
def build_chunk_id(chunk: ContentChunk) -> str:
|
|
238
|
+
return f"{chunk.id}_{chunk.chunk_id}"
|
|
239
|
+
|
|
240
|
+
referenced_chunks = [
|
|
241
|
+
chunk for chunk in selected_chunks if build_chunk_id(chunk) in reference_ids
|
|
242
|
+
]
|
|
243
|
+
|
|
244
|
+
return referenced_chunks
|
|
245
|
+
|
|
246
|
+
|
|
247
|
+
def _from_order_source_selection_mode(
|
|
248
|
+
references: list[ContentReference], selected_chunks: list[ContentChunk]
|
|
249
|
+
):
|
|
250
|
+
original_chunks_order: list[int] = []
|
|
251
|
+
for reference in references:
|
|
252
|
+
for original_index in reference.original_index:
|
|
253
|
+
if original_index not in original_chunks_order:
|
|
254
|
+
original_chunks_order.append(original_index)
|
|
255
|
+
|
|
256
|
+
referenced_chunks: list[ContentChunk] = []
|
|
257
|
+
for index in original_chunks_order:
|
|
258
|
+
referenced_chunks.append(selected_chunks[index])
|
|
259
|
+
|
|
260
|
+
return referenced_chunks
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
from unique_sdk.api_resources._agentic_table import (
|
|
2
|
+
ActivityStatus,
|
|
3
|
+
CellRendererTypes,
|
|
4
|
+
FilterTypes,
|
|
5
|
+
RowVerificationStatus,
|
|
6
|
+
)
|
|
7
|
+
|
|
8
|
+
from .schemas import (
|
|
9
|
+
AgenticTableSheetState,
|
|
10
|
+
AgreementStatus,
|
|
11
|
+
ArtifactType,
|
|
12
|
+
LogEntry,
|
|
13
|
+
MagicTableAction,
|
|
14
|
+
MagicTableAddMetadataPayload,
|
|
15
|
+
MagicTableBasePayload,
|
|
16
|
+
MagicTableCell,
|
|
17
|
+
MagicTableCellMetaData,
|
|
18
|
+
MagicTableEvent,
|
|
19
|
+
MagicTableEventTypes,
|
|
20
|
+
MagicTableGenerateArtifactPayload,
|
|
21
|
+
MagicTableLibrarySheetRowVerifiedPayload,
|
|
22
|
+
MagicTableSheet,
|
|
23
|
+
MagicTableSheetCompletedPayload,
|
|
24
|
+
MagicTableSheetCreatedPayload,
|
|
25
|
+
MagicTableUpdateCellPayload,
|
|
26
|
+
RowMetadataEntry,
|
|
27
|
+
SelectionMethod,
|
|
28
|
+
)
|
|
29
|
+
from .service import AgenticTableService
|
|
30
|
+
|
|
31
|
+
__all__ = [
|
|
32
|
+
"AgenticTableService",
|
|
33
|
+
"ActivityStatus",
|
|
34
|
+
"AgenticTableSheetState",
|
|
35
|
+
"AgreementStatus",
|
|
36
|
+
"ArtifactType",
|
|
37
|
+
"CellRendererTypes",
|
|
38
|
+
"FilterTypes",
|
|
39
|
+
"LogEntry",
|
|
40
|
+
"MagicTableAction",
|
|
41
|
+
"MagicTableAddMetadataPayload",
|
|
42
|
+
"MagicTableBasePayload",
|
|
43
|
+
"MagicTableCell",
|
|
44
|
+
"MagicTableCellMetaData",
|
|
45
|
+
"MagicTableEvent",
|
|
46
|
+
"MagicTableEventTypes",
|
|
47
|
+
"MagicTableGenerateArtifactPayload",
|
|
48
|
+
"MagicTableLibrarySheetRowVerifiedPayload",
|
|
49
|
+
"MagicTableSheet",
|
|
50
|
+
"MagicTableSheetCompletedPayload",
|
|
51
|
+
"MagicTableSheetCreatedPayload",
|
|
52
|
+
"MagicTableUpdateCellPayload",
|
|
53
|
+
"RowMetadataEntry",
|
|
54
|
+
"RowVerificationStatus",
|
|
55
|
+
"SelectionMethod",
|
|
56
|
+
]
|
|
@@ -0,0 +1,305 @@
|
|
|
1
|
+
from enum import StrEnum
|
|
2
|
+
from typing import Annotated, Any, Generic, Literal, TypeVar
|
|
3
|
+
|
|
4
|
+
from pydantic import (
|
|
5
|
+
BaseModel,
|
|
6
|
+
Field,
|
|
7
|
+
field_validator,
|
|
8
|
+
)
|
|
9
|
+
from unique_sdk import (
|
|
10
|
+
AgenticTableSheetState,
|
|
11
|
+
AgreementStatus,
|
|
12
|
+
SelectionMethod,
|
|
13
|
+
)
|
|
14
|
+
from unique_sdk import LogDetail as SDKLogDetail
|
|
15
|
+
from unique_sdk import LogEntry as SDKLogEntry
|
|
16
|
+
from unique_sdk.api_resources._agentic_table import (
|
|
17
|
+
MagicTableAction,
|
|
18
|
+
SheetType,
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
from unique_toolkit._common.pydantic_helpers import get_configuration_dict
|
|
22
|
+
from unique_toolkit.app.schemas import (
|
|
23
|
+
ChatEvent,
|
|
24
|
+
ChatEventAssistantMessage,
|
|
25
|
+
ChatEventUserMessage,
|
|
26
|
+
)
|
|
27
|
+
from unique_toolkit.language_model.schemas import (
|
|
28
|
+
LanguageModelMessageRole,
|
|
29
|
+
LanguageModelMessages,
|
|
30
|
+
)
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
class MagicTableEventTypes(StrEnum):
|
|
34
|
+
IMPORT_COLUMNS = "unique.magic-table.import-columns"
|
|
35
|
+
UPDATE_CELL = "unique.magic-table.update-cell"
|
|
36
|
+
ADD_DATA = "unique.magic-table.add-document"
|
|
37
|
+
ADD_META_DATA = "unique.magic-table.add-meta-data"
|
|
38
|
+
GENERATE_ARTIFACT = "unique.magic-table.generate-artifact"
|
|
39
|
+
SHEET_COMPLETED = "unique.magic-table.sheet-completed"
|
|
40
|
+
LIBRARY_SHEET_ROW_VERIFIED = "unique.magic-table.library-sheet-row.verified"
|
|
41
|
+
SHEET_CREATED = "unique.magic-table.sheet-created"
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
class BaseMetadata(BaseModel):
|
|
45
|
+
model_config = get_configuration_dict()
|
|
46
|
+
|
|
47
|
+
sheet_type: SheetType = Field(
|
|
48
|
+
description="The type of the sheet.",
|
|
49
|
+
default=SheetType.DEFAULT,
|
|
50
|
+
)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
class RowMetadataEntry(BaseModel):
|
|
54
|
+
model_config = get_configuration_dict()
|
|
55
|
+
id: str = Field(description="The ID of the metadata")
|
|
56
|
+
key: str = Field(description="The key of the metadata")
|
|
57
|
+
value: str = Field(description="The value of the metadata")
|
|
58
|
+
exact_filter: bool = Field(
|
|
59
|
+
default=False,
|
|
60
|
+
description="Whether the metadata is to be used for strict filtering",
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
class DDMetadata(BaseMetadata):
|
|
65
|
+
model_config = get_configuration_dict()
|
|
66
|
+
|
|
67
|
+
question_file_ids: list[str] = Field(
|
|
68
|
+
default_factory=list, description="The IDs of the question files"
|
|
69
|
+
)
|
|
70
|
+
source_file_ids: list[str] = Field(
|
|
71
|
+
default_factory=list, description="The IDs of the source files"
|
|
72
|
+
)
|
|
73
|
+
question_texts: list[str] = Field(
|
|
74
|
+
default_factory=list, description="The texts of the questions"
|
|
75
|
+
)
|
|
76
|
+
context: str = Field(default="", description="The context text for the table.")
|
|
77
|
+
|
|
78
|
+
@field_validator("context", mode="before")
|
|
79
|
+
@classmethod
|
|
80
|
+
def normalize_context(cls, v):
|
|
81
|
+
if v is None:
|
|
82
|
+
return ""
|
|
83
|
+
return v
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
# Define template types
|
|
87
|
+
A = TypeVar("A", bound=MagicTableAction)
|
|
88
|
+
T = TypeVar("T", bound=BaseMetadata)
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class MagicTableBasePayload(BaseModel, Generic[A, T]):
|
|
92
|
+
model_config = get_configuration_dict()
|
|
93
|
+
name: str = Field(description="The name of the module")
|
|
94
|
+
sheet_name: str
|
|
95
|
+
|
|
96
|
+
action: A
|
|
97
|
+
chat_id: str
|
|
98
|
+
assistant_id: str
|
|
99
|
+
table_id: str
|
|
100
|
+
user_message: ChatEventUserMessage = Field(
|
|
101
|
+
default=ChatEventUserMessage(
|
|
102
|
+
id="", text="", original_text="", created_at="", language=""
|
|
103
|
+
)
|
|
104
|
+
)
|
|
105
|
+
assistant_message: ChatEventAssistantMessage = Field(
|
|
106
|
+
default=ChatEventAssistantMessage(id="", created_at="")
|
|
107
|
+
)
|
|
108
|
+
configuration: dict[str, Any] = {}
|
|
109
|
+
metadata: T
|
|
110
|
+
metadata_filter: dict[str, Any] | None = None
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
########### Specialized Payload definitions ###########
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
class MagicTableAddMetadataPayload(
|
|
117
|
+
MagicTableBasePayload[Literal[MagicTableAction.ADD_META_DATA], DDMetadata]
|
|
118
|
+
): ...
|
|
119
|
+
|
|
120
|
+
|
|
121
|
+
class MagicTableUpdateCellPayload(
|
|
122
|
+
MagicTableBasePayload[Literal[MagicTableAction.UPDATE_CELL], DDMetadata]
|
|
123
|
+
):
|
|
124
|
+
column_order: int
|
|
125
|
+
row_order: int
|
|
126
|
+
data: str
|
|
127
|
+
|
|
128
|
+
|
|
129
|
+
class ArtifactType(StrEnum):
|
|
130
|
+
QUESTIONS = "QUESTIONS"
|
|
131
|
+
FULL_REPORT = "FULL_REPORT"
|
|
132
|
+
|
|
133
|
+
|
|
134
|
+
class ArtifactData(BaseModel):
|
|
135
|
+
model_config = get_configuration_dict()
|
|
136
|
+
artifact_type: ArtifactType
|
|
137
|
+
|
|
138
|
+
|
|
139
|
+
class MagicTableGenerateArtifactPayload(
|
|
140
|
+
MagicTableBasePayload[Literal[MagicTableAction.GENERATE_ARTIFACT], BaseMetadata]
|
|
141
|
+
):
|
|
142
|
+
data: ArtifactData
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
########## Sheet Completed Payload ##########
|
|
146
|
+
|
|
147
|
+
|
|
148
|
+
class SheetCompletedMetadata(BaseMetadata):
|
|
149
|
+
model_config = get_configuration_dict()
|
|
150
|
+
sheet_id: str = Field(description="The ID of the sheet that was completed.")
|
|
151
|
+
library_sheet_id: str = Field(
|
|
152
|
+
description="The ID of the library corresponding to the sheet."
|
|
153
|
+
)
|
|
154
|
+
context: str = Field(default="", description="The context text for the table.")
|
|
155
|
+
|
|
156
|
+
@field_validator("context", mode="before")
|
|
157
|
+
@classmethod
|
|
158
|
+
def normalize_context(cls, v):
|
|
159
|
+
if v is None:
|
|
160
|
+
return ""
|
|
161
|
+
return v
|
|
162
|
+
|
|
163
|
+
|
|
164
|
+
class MagicTableSheetCompletedPayload(
|
|
165
|
+
MagicTableBasePayload[
|
|
166
|
+
Literal[MagicTableAction.SHEET_COMPLETED], SheetCompletedMetadata
|
|
167
|
+
]
|
|
168
|
+
): ...
|
|
169
|
+
|
|
170
|
+
|
|
171
|
+
class SheetCreatedMetadata(BaseMetadata): ...
|
|
172
|
+
|
|
173
|
+
|
|
174
|
+
class MagicTableSheetCreatedPayload(
|
|
175
|
+
MagicTableBasePayload[Literal[MagicTableAction.SHEET_CREATED], SheetCreatedMetadata]
|
|
176
|
+
): ...
|
|
177
|
+
|
|
178
|
+
|
|
179
|
+
########## Library Sheet Row Verified Payload ##########
|
|
180
|
+
|
|
181
|
+
|
|
182
|
+
class LibrarySheetRowVerifiedMetadata(BaseMetadata):
|
|
183
|
+
model_config = get_configuration_dict()
|
|
184
|
+
row_order: int = Field(description="The row index of the row that was verified.")
|
|
185
|
+
|
|
186
|
+
|
|
187
|
+
class MagicTableLibrarySheetRowVerifiedPayload(
|
|
188
|
+
MagicTableBasePayload[
|
|
189
|
+
Literal[MagicTableAction.LIBRARY_SHEET_ROW_VERIFIED],
|
|
190
|
+
LibrarySheetRowVerifiedMetadata,
|
|
191
|
+
]
|
|
192
|
+
): ...
|
|
193
|
+
|
|
194
|
+
|
|
195
|
+
########### Magic Table Event definition ###########
|
|
196
|
+
|
|
197
|
+
|
|
198
|
+
PayloadTypes = (
|
|
199
|
+
MagicTableUpdateCellPayload
|
|
200
|
+
| MagicTableAddMetadataPayload
|
|
201
|
+
| MagicTableGenerateArtifactPayload
|
|
202
|
+
| MagicTableSheetCompletedPayload
|
|
203
|
+
| MagicTableLibrarySheetRowVerifiedPayload
|
|
204
|
+
| MagicTableSheetCreatedPayload
|
|
205
|
+
)
|
|
206
|
+
|
|
207
|
+
MagicTablePayloadTypes = Annotated[PayloadTypes, Field(discriminator="action")]
|
|
208
|
+
|
|
209
|
+
|
|
210
|
+
class MagicTableEvent(ChatEvent):
|
|
211
|
+
event: MagicTableEventTypes # type: ignore[assignment]
|
|
212
|
+
payload: MagicTablePayloadTypes # type: ignore[assignment]
|
|
213
|
+
|
|
214
|
+
|
|
215
|
+
class LogDetail(BaseModel):
|
|
216
|
+
model_config = get_configuration_dict()
|
|
217
|
+
llm_request: LanguageModelMessages | None = Field(
|
|
218
|
+
default=None, description="The LLM request for the log detail"
|
|
219
|
+
)
|
|
220
|
+
|
|
221
|
+
def to_sdk_log_detail(self) -> SDKLogDetail:
|
|
222
|
+
llm_request = None
|
|
223
|
+
if self.llm_request:
|
|
224
|
+
llm_request = self.llm_request.model_dump()
|
|
225
|
+
return SDKLogDetail(llmRequest=llm_request)
|
|
226
|
+
|
|
227
|
+
|
|
228
|
+
class LogEntry(BaseModel):
|
|
229
|
+
model_config = get_configuration_dict()
|
|
230
|
+
|
|
231
|
+
text: str
|
|
232
|
+
created_at: str
|
|
233
|
+
actor_type: LanguageModelMessageRole
|
|
234
|
+
message_id: str | None = None
|
|
235
|
+
details: LogDetail | None = Field(
|
|
236
|
+
default=None, description="The details of the log entry"
|
|
237
|
+
)
|
|
238
|
+
|
|
239
|
+
@field_validator("actor_type", mode="before")
|
|
240
|
+
@classmethod
|
|
241
|
+
def normalize_actor_type(cls, v):
|
|
242
|
+
if isinstance(v, str):
|
|
243
|
+
return v.lower()
|
|
244
|
+
return v
|
|
245
|
+
|
|
246
|
+
def to_sdk_log_entry(self) -> SDKLogEntry:
|
|
247
|
+
params: dict[str, Any] = {
|
|
248
|
+
"text": self.text,
|
|
249
|
+
"createdAt": self.created_at,
|
|
250
|
+
"actorType": self.actor_type.value.upper(),
|
|
251
|
+
}
|
|
252
|
+
if self.details:
|
|
253
|
+
params["details"] = self.details.to_sdk_log_detail()
|
|
254
|
+
|
|
255
|
+
return SDKLogEntry(**params)
|
|
256
|
+
|
|
257
|
+
|
|
258
|
+
class MagicTableCellMetaData(BaseModel):
|
|
259
|
+
model_config = get_configuration_dict()
|
|
260
|
+
row_order: int = Field(description="The row index of the cell.")
|
|
261
|
+
column_order: int = Field(description="The column index of the cell.")
|
|
262
|
+
selected: bool | None = None
|
|
263
|
+
selection_method: SelectionMethod | None = None
|
|
264
|
+
agreement_status: AgreementStatus | None = None
|
|
265
|
+
|
|
266
|
+
|
|
267
|
+
class MagicTableCell(BaseModel):
|
|
268
|
+
model_config = get_configuration_dict()
|
|
269
|
+
sheet_id: str
|
|
270
|
+
row_order: int = Field(description="The row index of the cell.")
|
|
271
|
+
column_order: int = Field(description="The column index of the cell.")
|
|
272
|
+
row_locked: bool = Field(default=False, description="Lock status of the row.")
|
|
273
|
+
text: str
|
|
274
|
+
log_entries: list[LogEntry] = Field(
|
|
275
|
+
default_factory=list, description="The log entries for the cell"
|
|
276
|
+
)
|
|
277
|
+
meta_data: MagicTableCellMetaData | None = Field(
|
|
278
|
+
default=None, description="The metadata for the cell"
|
|
279
|
+
)
|
|
280
|
+
row_metadata: list[RowMetadataEntry] = Field(
|
|
281
|
+
default_factory=list,
|
|
282
|
+
description="The metadata (key value pairs)for the rows.",
|
|
283
|
+
)
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
class MagicTableSheet(BaseModel):
|
|
287
|
+
model_config = get_configuration_dict()
|
|
288
|
+
sheet_id: str
|
|
289
|
+
name: str
|
|
290
|
+
state: AgenticTableSheetState
|
|
291
|
+
total_number_of_rows: int = Field(
|
|
292
|
+
default=0,
|
|
293
|
+
description="The total number of rows in the sheet",
|
|
294
|
+
alias="magicTableRowCount",
|
|
295
|
+
)
|
|
296
|
+
chat_id: str
|
|
297
|
+
created_by: str
|
|
298
|
+
company_id: str
|
|
299
|
+
created_at: str
|
|
300
|
+
magic_table_cells: list[MagicTableCell] = Field(
|
|
301
|
+
default_factory=list, description="The cells in the sheet"
|
|
302
|
+
)
|
|
303
|
+
magic_table_sheet_metadata: list[RowMetadataEntry] = Field(
|
|
304
|
+
default_factory=list, description="The metadata for the sheet"
|
|
305
|
+
)
|
|
@@ -0,0 +1,452 @@
|
|
|
1
|
+
import logging
|
|
2
|
+
|
|
3
|
+
from typing_extensions import deprecated
|
|
4
|
+
from unique_sdk import (
|
|
5
|
+
AgenticTable,
|
|
6
|
+
AgenticTableSheetState,
|
|
7
|
+
AgreementStatus,
|
|
8
|
+
CellRendererTypes,
|
|
9
|
+
FilterTypes,
|
|
10
|
+
RowVerificationStatus,
|
|
11
|
+
SelectionMethod,
|
|
12
|
+
)
|
|
13
|
+
from unique_sdk import AgenticTableCell as SDKAgenticTableCell
|
|
14
|
+
from unique_sdk.api_resources._agentic_table import ActivityStatus
|
|
15
|
+
|
|
16
|
+
from .schemas import (
|
|
17
|
+
ArtifactType,
|
|
18
|
+
LogEntry,
|
|
19
|
+
MagicTableAction,
|
|
20
|
+
MagicTableCell,
|
|
21
|
+
MagicTableSheet,
|
|
22
|
+
RowMetadataEntry,
|
|
23
|
+
)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
class LockedAgenticTableError(Exception):
|
|
27
|
+
pass
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
class AgenticTableService:
|
|
31
|
+
"""
|
|
32
|
+
Provides methods to interact with the Agentic Table.
|
|
33
|
+
|
|
34
|
+
Attributes:
|
|
35
|
+
#event (ChatEvent): The ChatEvent object.
|
|
36
|
+
logger (Optional[logging.Logger]): The logger object. Defaults to None.
|
|
37
|
+
"""
|
|
38
|
+
|
|
39
|
+
def __init__(
|
|
40
|
+
self,
|
|
41
|
+
user_id: str,
|
|
42
|
+
company_id: str,
|
|
43
|
+
table_id: str,
|
|
44
|
+
event_id: str | None = None,
|
|
45
|
+
logger: logging.Logger = logging.getLogger(__name__),
|
|
46
|
+
):
|
|
47
|
+
self._event_id = event_id
|
|
48
|
+
self._user_id = user_id
|
|
49
|
+
self._company_id = company_id
|
|
50
|
+
self.table_id = table_id
|
|
51
|
+
self.logger = logger
|
|
52
|
+
|
|
53
|
+
async def set_cell(
|
|
54
|
+
self,
|
|
55
|
+
row: int,
|
|
56
|
+
column: int,
|
|
57
|
+
text: str,
|
|
58
|
+
log_entries: list[LogEntry] | None = None,
|
|
59
|
+
):
|
|
60
|
+
"""
|
|
61
|
+
Sets the value of a cell in the Agentic Table.
|
|
62
|
+
|
|
63
|
+
Args:
|
|
64
|
+
row (int): The row index.
|
|
65
|
+
column (int): The column index.
|
|
66
|
+
text (str): The text to set.
|
|
67
|
+
log_entries (Optional[list[LogEntry]]): The log entries to set.
|
|
68
|
+
"""
|
|
69
|
+
if log_entries is None:
|
|
70
|
+
log_entries_new = []
|
|
71
|
+
else:
|
|
72
|
+
log_entries_new = [
|
|
73
|
+
log_entry.to_sdk_log_entry() for log_entry in log_entries
|
|
74
|
+
]
|
|
75
|
+
try:
|
|
76
|
+
await AgenticTable.set_cell(
|
|
77
|
+
user_id=self._user_id,
|
|
78
|
+
company_id=self._company_id,
|
|
79
|
+
tableId=self.table_id,
|
|
80
|
+
rowOrder=row,
|
|
81
|
+
columnOrder=column,
|
|
82
|
+
text=text,
|
|
83
|
+
logEntries=log_entries_new,
|
|
84
|
+
)
|
|
85
|
+
except Exception as e:
|
|
86
|
+
self.logger.error(f"Error setting cell {row}, {column}: {e}.")
|
|
87
|
+
|
|
88
|
+
async def get_cell(
|
|
89
|
+
self, row: int, column: int, include_row_metadata: bool = True
|
|
90
|
+
) -> MagicTableCell:
|
|
91
|
+
"""
|
|
92
|
+
Gets the value of a cell in the Agentic Table.
|
|
93
|
+
|
|
94
|
+
Args:
|
|
95
|
+
row (int): The row index.
|
|
96
|
+
column (int): The column index.
|
|
97
|
+
include_row_metadata (bool): Whether to include the row metadata. Defaults to True.
|
|
98
|
+
|
|
99
|
+
Returns:
|
|
100
|
+
MagicTableCell: The MagicTableCell object.
|
|
101
|
+
|
|
102
|
+
"""
|
|
103
|
+
cell_data = await AgenticTable.get_cell(
|
|
104
|
+
user_id=self._user_id,
|
|
105
|
+
company_id=self._company_id,
|
|
106
|
+
tableId=self.table_id,
|
|
107
|
+
rowOrder=row,
|
|
108
|
+
columnOrder=column,
|
|
109
|
+
includeRowMetadata=include_row_metadata, # type: ignore[arg-type]
|
|
110
|
+
)
|
|
111
|
+
return MagicTableCell.model_validate(cell_data)
|
|
112
|
+
|
|
113
|
+
async def set_multiple_cells(
|
|
114
|
+
self, cells: list[MagicTableCell], batch_size: int = 4000
|
|
115
|
+
):
|
|
116
|
+
"""
|
|
117
|
+
Sets the values of multiple cells in the Agentic Table.
|
|
118
|
+
|
|
119
|
+
Args:
|
|
120
|
+
cells (list[MagicTableCell]): The cells to set sorted by row and column.
|
|
121
|
+
batch_size (int): Number of cells to set in a single request.
|
|
122
|
+
"""
|
|
123
|
+
for i in range(0, len(cells), batch_size):
|
|
124
|
+
batch = cells[i : i + batch_size]
|
|
125
|
+
await AgenticTable.set_multiple_cells(
|
|
126
|
+
user_id=self._user_id,
|
|
127
|
+
company_id=self._company_id,
|
|
128
|
+
tableId=self.table_id,
|
|
129
|
+
cells=[
|
|
130
|
+
SDKAgenticTableCell(
|
|
131
|
+
rowOrder=cell.row_order,
|
|
132
|
+
columnOrder=cell.column_order,
|
|
133
|
+
text=cell.text,
|
|
134
|
+
)
|
|
135
|
+
for cell in batch
|
|
136
|
+
],
|
|
137
|
+
)
|
|
138
|
+
|
|
139
|
+
async def set_activity(
|
|
140
|
+
self,
|
|
141
|
+
text: str,
|
|
142
|
+
activity: MagicTableAction,
|
|
143
|
+
status: ActivityStatus = ActivityStatus.IN_PROGRESS,
|
|
144
|
+
):
|
|
145
|
+
"""
|
|
146
|
+
Sets the activity of the Agentic Table.
|
|
147
|
+
|
|
148
|
+
Args:
|
|
149
|
+
activity (str): The activity to set.
|
|
150
|
+
"""
|
|
151
|
+
await AgenticTable.set_activity(
|
|
152
|
+
user_id=self._user_id,
|
|
153
|
+
company_id=self._company_id,
|
|
154
|
+
tableId=self.table_id,
|
|
155
|
+
activity=activity.value, # type: ignore[arg-type]
|
|
156
|
+
status=status.value, # type: ignore[arg-type]
|
|
157
|
+
text=text,
|
|
158
|
+
)
|
|
159
|
+
|
|
160
|
+
async def register_agent(self) -> None:
|
|
161
|
+
"""
|
|
162
|
+
Registers the agent for the Agentic Table by updating the sheet state to PROCESSING.
|
|
163
|
+
|
|
164
|
+
Raises:
|
|
165
|
+
LockedAgenticTableError: If the Agentic Table is busy.
|
|
166
|
+
"""
|
|
167
|
+
state = await AgenticTable.get_sheet_state(
|
|
168
|
+
user_id=self._user_id,
|
|
169
|
+
company_id=self._company_id,
|
|
170
|
+
tableId=self.table_id,
|
|
171
|
+
)
|
|
172
|
+
if state == AgenticTableSheetState.IDLE:
|
|
173
|
+
await AgenticTable.update_sheet_state(
|
|
174
|
+
user_id=self._user_id,
|
|
175
|
+
company_id=self._company_id,
|
|
176
|
+
tableId=self.table_id,
|
|
177
|
+
state=AgenticTableSheetState.PROCESSING,
|
|
178
|
+
)
|
|
179
|
+
return
|
|
180
|
+
# If the sheet is not idle, we cannot register the agent
|
|
181
|
+
raise LockedAgenticTableError(
|
|
182
|
+
f"Agentic Table is busy. Cannot register agent {self._event_id or self.table_id}."
|
|
183
|
+
)
|
|
184
|
+
|
|
185
|
+
async def deregister_agent(self):
|
|
186
|
+
"""
|
|
187
|
+
Deregisters the agent for the Agentic Table by updating the sheet state to IDLE.
|
|
188
|
+
|
|
189
|
+
Raises:
|
|
190
|
+
LockedAgenticTableError: If the Agentic Table is busy.
|
|
191
|
+
"""
|
|
192
|
+
await AgenticTable.update_sheet_state(
|
|
193
|
+
user_id=self._user_id,
|
|
194
|
+
company_id=self._company_id,
|
|
195
|
+
tableId=self.table_id,
|
|
196
|
+
state=AgenticTableSheetState.IDLE,
|
|
197
|
+
)
|
|
198
|
+
|
|
199
|
+
async def set_artifact(
|
|
200
|
+
self,
|
|
201
|
+
artifact_type: ArtifactType,
|
|
202
|
+
content_id: str,
|
|
203
|
+
mime_type: str,
|
|
204
|
+
name: str,
|
|
205
|
+
):
|
|
206
|
+
"""Upload/set report files to the Agentic Table.
|
|
207
|
+
|
|
208
|
+
Args:
|
|
209
|
+
artifact_type (ArtifactType): The type of artifact to set.
|
|
210
|
+
content_id (str): The content ID of the artifact.
|
|
211
|
+
mime_type (str): The MIME type of the artifact.
|
|
212
|
+
name (str): The name of the artifact.
|
|
213
|
+
"""
|
|
214
|
+
await AgenticTable.set_artifact(
|
|
215
|
+
user_id=self._user_id,
|
|
216
|
+
company_id=self._company_id,
|
|
217
|
+
tableId=self.table_id,
|
|
218
|
+
artifactType=artifact_type.value,
|
|
219
|
+
contentId=content_id,
|
|
220
|
+
mimeType=mime_type,
|
|
221
|
+
name=name,
|
|
222
|
+
)
|
|
223
|
+
|
|
224
|
+
@deprecated("Use set_column_style instead.")
|
|
225
|
+
async def set_column_width(self, column: int, width: int):
|
|
226
|
+
await self.set_column_style(column=column, width=width)
|
|
227
|
+
|
|
228
|
+
async def set_column_style(
|
|
229
|
+
self,
|
|
230
|
+
column: int,
|
|
231
|
+
width: int | None = None,
|
|
232
|
+
cell_renderer: CellRendererTypes | None = None,
|
|
233
|
+
filter: FilterTypes | None = None,
|
|
234
|
+
editable: bool | None = None,
|
|
235
|
+
):
|
|
236
|
+
"""
|
|
237
|
+
Sets the style of a column in the Agentic Table.
|
|
238
|
+
|
|
239
|
+
Args:
|
|
240
|
+
column (int): The column index.
|
|
241
|
+
width (int | None, optional): The width of the column. Defaults to None.
|
|
242
|
+
cell_renderer (CellRenderer | None, optional): The cell renderer of the column. Defaults to None.
|
|
243
|
+
filter (FilterComponents | None, optional): The filter of the column. Defaults to None.
|
|
244
|
+
editable (bool | None, optional): Whether the column is editable. Defaults to None.
|
|
245
|
+
|
|
246
|
+
Raises:
|
|
247
|
+
Exception: If the column style is not set.
|
|
248
|
+
"""
|
|
249
|
+
# Convert the input to the correct format
|
|
250
|
+
params = {}
|
|
251
|
+
if width is not None:
|
|
252
|
+
params["columnWidth"] = width
|
|
253
|
+
if cell_renderer is not None:
|
|
254
|
+
params["cellRenderer"] = cell_renderer.value
|
|
255
|
+
if filter is not None:
|
|
256
|
+
params["filter"] = filter.value
|
|
257
|
+
if editable is not None:
|
|
258
|
+
params["editable"] = editable
|
|
259
|
+
status, message = await AgenticTable.set_column_metadata(
|
|
260
|
+
user_id=self._user_id,
|
|
261
|
+
company_id=self._company_id,
|
|
262
|
+
tableId=self.table_id,
|
|
263
|
+
columnOrder=column,
|
|
264
|
+
**params,
|
|
265
|
+
)
|
|
266
|
+
if status:
|
|
267
|
+
return
|
|
268
|
+
raise Exception(message)
|
|
269
|
+
|
|
270
|
+
async def get_num_rows(self) -> int:
|
|
271
|
+
"""
|
|
272
|
+
Gets the number of rows in the Agentic Table.
|
|
273
|
+
|
|
274
|
+
Returns:
|
|
275
|
+
int: The number of rows in the Agentic Table.
|
|
276
|
+
"""
|
|
277
|
+
sheet_info = await AgenticTable.get_sheet_data(
|
|
278
|
+
user_id=self._user_id,
|
|
279
|
+
company_id=self._company_id,
|
|
280
|
+
tableId=self.table_id,
|
|
281
|
+
includeRowCount=True,
|
|
282
|
+
includeCells=False,
|
|
283
|
+
includeLogHistory=False,
|
|
284
|
+
)
|
|
285
|
+
return sheet_info["magicTableRowCount"]
|
|
286
|
+
|
|
287
|
+
async def get_sheet(
|
|
288
|
+
self,
|
|
289
|
+
start_row: int = 0,
|
|
290
|
+
end_row: int | None = None,
|
|
291
|
+
batch_size: int = 100,
|
|
292
|
+
include_log_history: bool = False,
|
|
293
|
+
include_cell_meta_data: bool = False,
|
|
294
|
+
include_row_metadata: bool = False,
|
|
295
|
+
) -> MagicTableSheet:
|
|
296
|
+
"""
|
|
297
|
+
Gets the sheet data from the Agentic Table paginated by batch_size.
|
|
298
|
+
|
|
299
|
+
Args:
|
|
300
|
+
start_row (int): The start row (inclusive).
|
|
301
|
+
end_row (int | None): The end row (not inclusive).
|
|
302
|
+
batch_size (int): The batch size.
|
|
303
|
+
include_log_history (bool): Whether to include the log history.
|
|
304
|
+
include_cell_meta_data (bool): Whether to include the cell metadata (renderer, selection, agreement status).
|
|
305
|
+
include_row_metadata (bool): Whether to include the row metadata (key value pairs).
|
|
306
|
+
Returns:
|
|
307
|
+
MagicTableSheet: The sheet data.
|
|
308
|
+
"""
|
|
309
|
+
# Find the total number of rows
|
|
310
|
+
sheet_info = await AgenticTable.get_sheet_data(
|
|
311
|
+
user_id=self._user_id,
|
|
312
|
+
company_id=self._company_id,
|
|
313
|
+
tableId=self.table_id,
|
|
314
|
+
includeRowCount=True,
|
|
315
|
+
includeCells=False,
|
|
316
|
+
includeLogHistory=False,
|
|
317
|
+
includeCellMetaData=False,
|
|
318
|
+
)
|
|
319
|
+
total_rows = sheet_info["magicTableRowCount"]
|
|
320
|
+
if end_row is None or end_row > total_rows:
|
|
321
|
+
end_row = total_rows
|
|
322
|
+
if start_row > end_row:
|
|
323
|
+
raise Exception("Start row is greater than end row")
|
|
324
|
+
if start_row < 0 or end_row < 0:
|
|
325
|
+
raise Exception("Start row or end row is negative")
|
|
326
|
+
|
|
327
|
+
# Get the cells
|
|
328
|
+
cells = []
|
|
329
|
+
for row in range(start_row, end_row, batch_size):
|
|
330
|
+
end_row_batch = min(row + batch_size, end_row)
|
|
331
|
+
sheet_partial = await AgenticTable.get_sheet_data(
|
|
332
|
+
user_id=self._user_id,
|
|
333
|
+
company_id=self._company_id,
|
|
334
|
+
tableId=self.table_id,
|
|
335
|
+
includeCells=True,
|
|
336
|
+
includeLogHistory=include_log_history,
|
|
337
|
+
includeRowCount=False,
|
|
338
|
+
includeCellMetaData=include_cell_meta_data, # renderer, selection, agreement status
|
|
339
|
+
startRow=row,
|
|
340
|
+
endRow=end_row_batch - 1,
|
|
341
|
+
)
|
|
342
|
+
if "magicTableCells" in sheet_partial:
|
|
343
|
+
if include_row_metadata:
|
|
344
|
+
# If include_row_metadata is true, we need to get the row metadata for each cell.
|
|
345
|
+
row_metadata_map = {}
|
|
346
|
+
# TODO: @thea-unique This routine is not efficient and would be nice if we had this data passed on in get_sheet_data.
|
|
347
|
+
for cell in sheet_partial["magicTableCells"]:
|
|
348
|
+
row_order = cell.get("rowOrder") # type: ignore[assignment]
|
|
349
|
+
if row_order is not None and row_order not in row_metadata_map:
|
|
350
|
+
column_order = cell.get("columnOrder") # type: ignore[assignment]
|
|
351
|
+
self.logger.info(
|
|
352
|
+
f"Getting row metadata for cell {row_order}, {column_order}"
|
|
353
|
+
)
|
|
354
|
+
cell_with_row_metadata = await self.get_cell(
|
|
355
|
+
row_order,
|
|
356
|
+
column_order, # type: ignore[arg-type]
|
|
357
|
+
)
|
|
358
|
+
if cell_with_row_metadata.row_metadata:
|
|
359
|
+
print(cell_with_row_metadata.row_metadata)
|
|
360
|
+
row_metadata_map[cell_with_row_metadata.row_order] = (
|
|
361
|
+
cell_with_row_metadata.row_metadata
|
|
362
|
+
)
|
|
363
|
+
cell["rowMetadata"] = ( # type: ignore[assignment]
|
|
364
|
+
cell_with_row_metadata.row_metadata
|
|
365
|
+
)
|
|
366
|
+
# Assign row_metadata to all cells
|
|
367
|
+
for cell in sheet_partial["magicTableCells"]:
|
|
368
|
+
row_order = cell.get("rowOrder") # type: ignore[assignment]
|
|
369
|
+
if row_order is not None and row_order in row_metadata_map:
|
|
370
|
+
cell["rowMetadata"] = row_metadata_map[ # type: ignore[assignment]
|
|
371
|
+
row_order
|
|
372
|
+
]
|
|
373
|
+
|
|
374
|
+
cells.extend(sheet_partial["magicTableCells"])
|
|
375
|
+
|
|
376
|
+
sheet_info["magicTableCells"] = cells
|
|
377
|
+
return MagicTableSheet.model_validate(sheet_info)
|
|
378
|
+
|
|
379
|
+
async def get_sheet_metadata(self) -> list[RowMetadataEntry]:
|
|
380
|
+
"""
|
|
381
|
+
Gets the sheet metadata from the Agentic Table.
|
|
382
|
+
|
|
383
|
+
Returns:
|
|
384
|
+
list[RowMetadataEntry]: The sheet metadata.
|
|
385
|
+
"""
|
|
386
|
+
sheet_info = await AgenticTable.get_sheet_data(
|
|
387
|
+
user_id=self._user_id,
|
|
388
|
+
company_id=self._company_id,
|
|
389
|
+
tableId=self.table_id,
|
|
390
|
+
includeSheetMetadata=True, # type: ignore[arg-type]
|
|
391
|
+
)
|
|
392
|
+
return [
|
|
393
|
+
RowMetadataEntry.model_validate(metadata)
|
|
394
|
+
for metadata in sheet_info["magicTableSheetMetadata"]
|
|
395
|
+
]
|
|
396
|
+
|
|
397
|
+
async def set_cell_metadata(
|
|
398
|
+
self,
|
|
399
|
+
row: int,
|
|
400
|
+
column: int,
|
|
401
|
+
selected: bool | None = None,
|
|
402
|
+
selection_method: SelectionMethod | None = None,
|
|
403
|
+
agreement_status: AgreementStatus | None = None,
|
|
404
|
+
) -> None:
|
|
405
|
+
"""
|
|
406
|
+
Sets the cell metadata for the Agentic Table.
|
|
407
|
+
NOTE: This is not to be confused with the sheet metadata and is associated rather with selection and agreement status, row locking etc.
|
|
408
|
+
|
|
409
|
+
Args:
|
|
410
|
+
row (int): The row index.
|
|
411
|
+
column (int): The column index.
|
|
412
|
+
selected (bool | None): Whether the cell is selected.
|
|
413
|
+
selection_method (SelectionMethod | None): The method of selection.
|
|
414
|
+
agreement_status (AgreementStatus | None): The agreement status.
|
|
415
|
+
"""
|
|
416
|
+
params = {}
|
|
417
|
+
if selected is not None:
|
|
418
|
+
params["selected"] = selected
|
|
419
|
+
if selection_method is not None:
|
|
420
|
+
params["selectionMethod"] = selection_method
|
|
421
|
+
if agreement_status is not None:
|
|
422
|
+
params["agreementStatus"] = agreement_status
|
|
423
|
+
result = await AgenticTable.set_cell_metadata(
|
|
424
|
+
user_id=self._user_id,
|
|
425
|
+
company_id=self._company_id,
|
|
426
|
+
tableId=self.table_id,
|
|
427
|
+
rowOrder=row,
|
|
428
|
+
columnOrder=column,
|
|
429
|
+
**params,
|
|
430
|
+
)
|
|
431
|
+
if result["status"]: # type: ignore
|
|
432
|
+
return
|
|
433
|
+
raise Exception(result["message"]) # type: ignore
|
|
434
|
+
|
|
435
|
+
async def update_row_verification_status(
|
|
436
|
+
self,
|
|
437
|
+
row_orders: list[int],
|
|
438
|
+
status: RowVerificationStatus,
|
|
439
|
+
):
|
|
440
|
+
"""Update the verification status of multiple rows at once.
|
|
441
|
+
|
|
442
|
+
Args:
|
|
443
|
+
row_orders (list[int]): The row indexes to update.
|
|
444
|
+
status (RowVerificationStatus): The verification status to set.
|
|
445
|
+
"""
|
|
446
|
+
await AgenticTable.bulk_update_status(
|
|
447
|
+
user_id=self._user_id,
|
|
448
|
+
company_id=self._company_id,
|
|
449
|
+
tableId=self.table_id,
|
|
450
|
+
rowOrders=row_orders,
|
|
451
|
+
status=status,
|
|
452
|
+
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import json
|
|
2
2
|
from logging import getLogger
|
|
3
|
-
from typing import TYPE_CHECKING, Any, Callable, TypeVar
|
|
3
|
+
from typing import TYPE_CHECKING, Any, Awaitable, Callable, TypeVar
|
|
4
4
|
|
|
5
5
|
from pydantic import ValidationError
|
|
6
6
|
|
|
@@ -35,13 +35,15 @@ def default_event_handler(event: Any) -> int:
|
|
|
35
35
|
|
|
36
36
|
T = TypeVar("T", bound=BaseEvent)
|
|
37
37
|
|
|
38
|
+
EventHandlerType = Callable[[T], Awaitable[int]] | Callable[[T], int]
|
|
39
|
+
|
|
38
40
|
|
|
39
41
|
def build_unique_custom_app(
|
|
40
42
|
*,
|
|
41
43
|
title: str = "Unique Chat App",
|
|
42
44
|
webhook_path: str = "/webhook",
|
|
43
45
|
settings: UniqueSettings,
|
|
44
|
-
event_handler:
|
|
46
|
+
event_handler: EventHandlerType = default_event_handler,
|
|
45
47
|
event_constructor: Callable[..., T] = ChatEvent,
|
|
46
48
|
subscribed_event_names: list[str] | None = None,
|
|
47
49
|
) -> "FastAPI":
|
|
@@ -106,11 +108,17 @@ def build_unique_custom_app(
|
|
|
106
108
|
|
|
107
109
|
try:
|
|
108
110
|
event = event_constructor(**event_data)
|
|
109
|
-
if
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
111
|
+
if (
|
|
112
|
+
settings.chat_event_filter_options
|
|
113
|
+
and settings.chat_event_filter_options.assistant_ids
|
|
114
|
+
):
|
|
115
|
+
if event.filter_event(
|
|
116
|
+
filter_options=settings.chat_event_filter_options
|
|
117
|
+
):
|
|
118
|
+
return JSONResponse(
|
|
119
|
+
status_code=status.HTTP_200_OK,
|
|
120
|
+
content={"error": "Event filtered out"},
|
|
121
|
+
)
|
|
114
122
|
except ValidationError as e:
|
|
115
123
|
# pydantic errors https://docs.pydantic.dev/2.10/errors/errors/
|
|
116
124
|
logger.error(f"Validation error with model: {e.json()}", exc_info=True)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: unique_toolkit
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.41.0
|
|
4
4
|
Summary:
|
|
5
5
|
License: Proprietary
|
|
6
6
|
Author: Cedric Klinkert
|
|
@@ -123,6 +123,13 @@ All notable changes to this project will be documented in this file.
|
|
|
123
123
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
124
124
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
125
125
|
|
|
126
|
+
|
|
127
|
+
## [1.41.0] - 2025-12-29
|
|
128
|
+
- Add `AgenticTable` service to unique_toolkit
|
|
129
|
+
|
|
130
|
+
## [1.40.0] - 2025-12-22
|
|
131
|
+
- Add option to use retrieve referenced chunks from their order
|
|
132
|
+
|
|
126
133
|
## [1.40.0] - 2025-12-22
|
|
127
134
|
- Add `hide_in_chat` parameter to `upload_to_chat_from_bytes` and `upload_to_chat_from_bytes_async`
|
|
128
135
|
- Hide code interpreter files in chat
|
|
@@ -54,7 +54,7 @@ unique_toolkit/agentic/evaluation/hallucination/constants.py,sha256=SoGmoYti2J33
|
|
|
54
54
|
unique_toolkit/agentic/evaluation/hallucination/hallucination_evaluation.py,sha256=x5ta2Fum4fE5ySgIXPKlnbTtmV140z0IazSATd0-REg,4092
|
|
55
55
|
unique_toolkit/agentic/evaluation/hallucination/prompts.py,sha256=O3Hi_rOzZlujvnO2wn2jhoPmrYLjzVtRWwxn5Q81m9Y,3405
|
|
56
56
|
unique_toolkit/agentic/evaluation/hallucination/service.py,sha256=WJF1f45uHnYLx1S4TW31bSFobFpV-YlOS3G_zMhuBVU,2512
|
|
57
|
-
unique_toolkit/agentic/evaluation/hallucination/utils.py,sha256=
|
|
57
|
+
unique_toolkit/agentic/evaluation/hallucination/utils.py,sha256=uHKTJw4kJyq0_Gi-EOhbocBAij4_Vzn3dW1wTxAuFg4,9706
|
|
58
58
|
unique_toolkit/agentic/evaluation/output_parser.py,sha256=0FDo8YY_Dc4qlTNeYyQkznzIFj9aX9wMrLOTbhhTl6g,1418
|
|
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
|
|
@@ -137,9 +137,12 @@ unique_toolkit/agentic/tools/utils/source_handling/__init__.py,sha256=47DEQpj8HB
|
|
|
137
137
|
unique_toolkit/agentic/tools/utils/source_handling/schema.py,sha256=iHBKuks6tUy8tvian4Pd0B6_-8__SehVVNcxIUAUjEA,882
|
|
138
138
|
unique_toolkit/agentic/tools/utils/source_handling/source_formatting.py,sha256=uZ0QXqrPWgId3ZA67dvjHQ6xrW491LK1xxx_sVJmFHg,9160
|
|
139
139
|
unique_toolkit/agentic/tools/utils/source_handling/tests/test_source_formatting.py,sha256=EA8iVvb3L91OFk2XMbGcFuhe2etqm3Sx9QCYDGiOSOM,6995
|
|
140
|
+
unique_toolkit/agentic_table/__init__.py,sha256=smJFstF5qH35RmZfzJUigdsVgUVNOza9KxMbraWrm9E,1411
|
|
141
|
+
unique_toolkit/agentic_table/schemas.py,sha256=VOEp3yjpgE3j1plPAlWNoQ16tDB3pBvu6HsS9WSqdu0,8907
|
|
142
|
+
unique_toolkit/agentic_table/service.py,sha256=Bgi0B_AT7Mswbud3VI-pNcnc_85xFu4S1dbLttYF7yY,16290
|
|
140
143
|
unique_toolkit/app/__init__.py,sha256=OaylhLwxeRlsHlcFGSlR5R7oREFsjv9wRdxuVZBYM_8,1371
|
|
141
144
|
unique_toolkit/app/dev_util.py,sha256=J20peCvrSQKfMGdYPYwCirs3Yq2v_e33GzNBzNKbWN4,5531
|
|
142
|
-
unique_toolkit/app/fast_api_factory.py,sha256=
|
|
145
|
+
unique_toolkit/app/fast_api_factory.py,sha256=4xoN23abH4LnRsM9atu97WEHK3-nH29LiWsI50whH_U,4923
|
|
143
146
|
unique_toolkit/app/init_logging.py,sha256=Sh26SRxOj8i8dzobKhYha2lLrkrMTHfB1V4jR3h23gQ,678
|
|
144
147
|
unique_toolkit/app/init_sdk.py,sha256=5_oDoETr6akwYyBCb0ivTdMNu3SVgPSkrXcDS6ELyY8,2269
|
|
145
148
|
unique_toolkit/app/performance/async_tasks.py,sha256=H0l3OAcosLwNHZ8d2pd-Di4wHIXfclEvagi5kfqLFPA,1941
|
|
@@ -212,7 +215,7 @@ unique_toolkit/short_term_memory/service.py,sha256=5PeVBu1ZCAfyDb2HLVvlmqSbyzBBu
|
|
|
212
215
|
unique_toolkit/smart_rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
213
216
|
unique_toolkit/smart_rules/compile.py,sha256=Ozhh70qCn2yOzRWr9d8WmJeTo7AQurwd3tStgBMPFLA,1246
|
|
214
217
|
unique_toolkit/test_utilities/events.py,sha256=_mwV2bs5iLjxS1ynDCjaIq-gjjKhXYCK-iy3dRfvO3g,6410
|
|
215
|
-
unique_toolkit-1.
|
|
216
|
-
unique_toolkit-1.
|
|
217
|
-
unique_toolkit-1.
|
|
218
|
-
unique_toolkit-1.
|
|
218
|
+
unique_toolkit-1.41.0.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
|
|
219
|
+
unique_toolkit-1.41.0.dist-info/METADATA,sha256=nfWPkb3z7-IQBPeeLrcFN8AJm2MmuwPGlA9t-5XgStY,46495
|
|
220
|
+
unique_toolkit-1.41.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
|
221
|
+
unique_toolkit-1.41.0.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|