unique_toolkit 0.5.50__py3-none-any.whl → 0.5.52__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/chat/__init__.py +4 -0
- unique_toolkit/chat/schemas.py +35 -0
- unique_toolkit/chat/service.py +170 -1
- unique_toolkit/language_model/service.py +17 -5
- {unique_toolkit-0.5.50.dist-info → unique_toolkit-0.5.52.dist-info}/METADATA +10 -4
- {unique_toolkit-0.5.50.dist-info → unique_toolkit-0.5.52.dist-info}/RECORD +8 -8
- {unique_toolkit-0.5.50.dist-info → unique_toolkit-0.5.52.dist-info}/LICENSE +0 -0
- {unique_toolkit-0.5.50.dist-info → unique_toolkit-0.5.52.dist-info}/WHEEL +0 -0
unique_toolkit/chat/__init__.py
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
from .schemas import ChatMessage as ChatMessage
|
2
2
|
from .schemas import ChatMessageRole as ChatMessageRole
|
3
|
+
from .schemas import MessageAssessment as MessageAssessment
|
4
|
+
from .schemas import MessageAssessmentLabel as MessageAssessmentLabel
|
5
|
+
from .schemas import MessageAssessmentStatus as MessageAssessmentStatus
|
6
|
+
from .schemas import MessageAssessmentType as MessageAssessmentType
|
3
7
|
from .service import ChatService as ChatService
|
4
8
|
from .utils import (
|
5
9
|
convert_chat_history_to_injectable_string as convert_chat_history_to_injectable_string,
|
unique_toolkit/chat/schemas.py
CHANGED
@@ -1,3 +1,4 @@
|
|
1
|
+
from datetime import datetime
|
1
2
|
from enum import StrEnum
|
2
3
|
from typing import Optional
|
3
4
|
|
@@ -60,3 +61,37 @@ class ChatMessage(BaseModel):
|
|
60
61
|
if self.role == ChatMessageRole.TOOL and not self.tool_call_id:
|
61
62
|
raise ValueError("tool_call_ids is required when role is 'tool'")
|
62
63
|
return self
|
64
|
+
|
65
|
+
|
66
|
+
class MessageAssessmentStatus(StrEnum):
|
67
|
+
PENDING = "PENDING"
|
68
|
+
DONE = "DONE"
|
69
|
+
ERROR = "ERROR"
|
70
|
+
|
71
|
+
|
72
|
+
class MessageAssessmentLabel(StrEnum):
|
73
|
+
POSITIVE = "POSITIVE"
|
74
|
+
NEGATIVE = "NEGATIVE"
|
75
|
+
VERIFIED = "VERIFIED"
|
76
|
+
UNVERIFIED = "UNVERIFIED"
|
77
|
+
|
78
|
+
|
79
|
+
class MessageAssessmentType(StrEnum):
|
80
|
+
HALLUCINATION = "HALLUCINATION"
|
81
|
+
COMPLIANCE = "COMPLIANCE"
|
82
|
+
|
83
|
+
|
84
|
+
class MessageAssessment(BaseModel):
|
85
|
+
model_config = model_config
|
86
|
+
|
87
|
+
id: str
|
88
|
+
object: str
|
89
|
+
message_id: str
|
90
|
+
assistant_message_id: str
|
91
|
+
status: MessageAssessmentStatus
|
92
|
+
explanation: str
|
93
|
+
label: MessageAssessmentLabel
|
94
|
+
type: MessageAssessmentType
|
95
|
+
is_visible: bool
|
96
|
+
created_at: datetime
|
97
|
+
updated_at: datetime
|
unique_toolkit/chat/service.py
CHANGED
@@ -8,7 +8,14 @@ from unique_sdk._list_object import ListObject
|
|
8
8
|
from unique_toolkit._common import _time_utils
|
9
9
|
from unique_toolkit._common._base_service import BaseService
|
10
10
|
from unique_toolkit.app.schemas import Event
|
11
|
-
from unique_toolkit.chat.schemas import
|
11
|
+
from unique_toolkit.chat.schemas import (
|
12
|
+
ChatMessage,
|
13
|
+
ChatMessageRole,
|
14
|
+
MessageAssessment,
|
15
|
+
MessageAssessmentLabel,
|
16
|
+
MessageAssessmentStatus,
|
17
|
+
MessageAssessmentType,
|
18
|
+
)
|
12
19
|
from unique_toolkit.content.schemas import ContentReference
|
13
20
|
from unique_toolkit.content.utils import count_tokens
|
14
21
|
|
@@ -587,3 +594,165 @@ class ChatService(BaseService):
|
|
587
594
|
"completedAt": completed_at_datetime,
|
588
595
|
}
|
589
596
|
return params
|
597
|
+
|
598
|
+
def create_message_assessment(
|
599
|
+
self,
|
600
|
+
assistant_message_id: str,
|
601
|
+
status: MessageAssessmentStatus,
|
602
|
+
explanation: str,
|
603
|
+
label: MessageAssessmentLabel,
|
604
|
+
type: MessageAssessmentType,
|
605
|
+
is_visible: bool = True,
|
606
|
+
) -> MessageAssessment:
|
607
|
+
"""
|
608
|
+
Creates a message assessment for an assistant message synchronously.
|
609
|
+
|
610
|
+
Args:
|
611
|
+
assistant_message_id (str): The ID of the assistant message to assess
|
612
|
+
status (MessageAssessmentStatus): The status of the assessment (e.g. "DONE")
|
613
|
+
explanation (str): Explanation of the assessment
|
614
|
+
label (MessageAssessmentLabel): The assessment label (e.g. "NEGATIVE")
|
615
|
+
type (MessageAssessmentType): The type of assessment (e.g. "HALLUCINATION")
|
616
|
+
is_visible (bool): Whether the assessment is visible to users. Defaults to True.
|
617
|
+
|
618
|
+
Returns:
|
619
|
+
MessageAssessment: The created message assessment
|
620
|
+
|
621
|
+
Raises:
|
622
|
+
Exception: If the creation fails
|
623
|
+
"""
|
624
|
+
try:
|
625
|
+
assessment = unique_sdk.MessageAssessment.create(
|
626
|
+
user_id=self.event.user_id,
|
627
|
+
company_id=self.event.company_id,
|
628
|
+
assistant_message_id=assistant_message_id,
|
629
|
+
status=status.name,
|
630
|
+
explanation=explanation,
|
631
|
+
label=label.name,
|
632
|
+
type=type.name,
|
633
|
+
isVisible=is_visible,
|
634
|
+
)
|
635
|
+
return MessageAssessment(**assessment)
|
636
|
+
except Exception as e:
|
637
|
+
self.logger.error(f"Failed to create message assessment: {e}")
|
638
|
+
raise e
|
639
|
+
|
640
|
+
async def create_message_assessment_async(
|
641
|
+
self,
|
642
|
+
assistant_message_id: str,
|
643
|
+
status: MessageAssessmentStatus,
|
644
|
+
explanation: str,
|
645
|
+
label: MessageAssessmentLabel,
|
646
|
+
type: MessageAssessmentType,
|
647
|
+
is_visible: bool = True,
|
648
|
+
) -> MessageAssessment:
|
649
|
+
"""
|
650
|
+
Creates a message assessment for an assistant message asynchronously.
|
651
|
+
|
652
|
+
Args:
|
653
|
+
assistant_message_id (str): The ID of the assistant message to assess
|
654
|
+
status (MessageAssessmentStatus): The status of the assessment (e.g. "DONE")
|
655
|
+
explanation (str): Explanation of the assessment
|
656
|
+
label (MessageAssessmentLabel): The assessment label (e.g. "NEGATIVE")
|
657
|
+
type (MessageAssessmentType): The type of assessment (e.g. "HALLUCINATION")
|
658
|
+
is_visible (bool): Whether the assessment is visible to users. Defaults to True.
|
659
|
+
|
660
|
+
Returns:
|
661
|
+
MessageAssessment: The created message assessment
|
662
|
+
|
663
|
+
Raises:
|
664
|
+
Exception: If the creation fails
|
665
|
+
"""
|
666
|
+
try:
|
667
|
+
assessment = await unique_sdk.MessageAssessment.create_async(
|
668
|
+
user_id=self.event.user_id,
|
669
|
+
company_id=self.event.company_id,
|
670
|
+
assistant_message_id=assistant_message_id,
|
671
|
+
status=status.name,
|
672
|
+
explanation=explanation,
|
673
|
+
label=label.name,
|
674
|
+
type=type.name,
|
675
|
+
isVisible=is_visible,
|
676
|
+
)
|
677
|
+
return MessageAssessment(**assessment)
|
678
|
+
except Exception as e:
|
679
|
+
self.logger.error(f"Failed to create message assessment: {e}")
|
680
|
+
raise e
|
681
|
+
|
682
|
+
def modify_message_assessment(
|
683
|
+
self,
|
684
|
+
assistant_message_id: str,
|
685
|
+
status: MessageAssessmentStatus,
|
686
|
+
explanation: str,
|
687
|
+
label: MessageAssessmentLabel,
|
688
|
+
type: MessageAssessmentType,
|
689
|
+
) -> MessageAssessment:
|
690
|
+
"""
|
691
|
+
Modifies a message assessment for an assistant message synchronously.
|
692
|
+
|
693
|
+
Args:
|
694
|
+
assistant_message_id (str): The ID of the assistant message to assess
|
695
|
+
status (MessageAssessmentStatus): The status of the assessment (e.g. "DONE")
|
696
|
+
explanation (str): Explanation of the assessment
|
697
|
+
label (MessageAssessmentLabel): The assessment label (e.g. "NEGATIVE")
|
698
|
+
type (MessageAssessmentType): The type of assessment (e.g. "HALLUCINATION")
|
699
|
+
|
700
|
+
Returns:
|
701
|
+
dict: The modified message assessment
|
702
|
+
|
703
|
+
Raises:
|
704
|
+
Exception: If the modification fails
|
705
|
+
"""
|
706
|
+
try:
|
707
|
+
assessment = unique_sdk.MessageAssessment.modify(
|
708
|
+
user_id=self.event.user_id,
|
709
|
+
company_id=self.event.company_id,
|
710
|
+
assistant_message_id=assistant_message_id,
|
711
|
+
status=status.name,
|
712
|
+
explanation=explanation,
|
713
|
+
label=label.name,
|
714
|
+
type=type.name,
|
715
|
+
)
|
716
|
+
return MessageAssessment(**assessment)
|
717
|
+
except Exception as e:
|
718
|
+
self.logger.error(f"Failed to modify message assessment: {e}")
|
719
|
+
raise e
|
720
|
+
|
721
|
+
async def modify_message_assessment_async(
|
722
|
+
self,
|
723
|
+
assistant_message_id: str,
|
724
|
+
status: MessageAssessmentStatus,
|
725
|
+
explanation: str,
|
726
|
+
label: MessageAssessmentLabel,
|
727
|
+
type: MessageAssessmentType,
|
728
|
+
) -> MessageAssessment:
|
729
|
+
"""
|
730
|
+
Modifies a message assessment for an assistant message asynchronously.
|
731
|
+
|
732
|
+
Args:
|
733
|
+
assistant_message_id (str): The ID of the assistant message to assess
|
734
|
+
status (MessageAssessmentStatus): The status of the assessment (e.g. "DONE")
|
735
|
+
explanation (str): Explanation of the assessment
|
736
|
+
label (MessageAssessmentLabel): The assessment label (e.g. "NEGATIVE")
|
737
|
+
type (MessageAssessmentType): The type of assessment (e.g. "HALLUCINATION")
|
738
|
+
|
739
|
+
Returns:
|
740
|
+
MessageAssessment: The modified message assessment
|
741
|
+
|
742
|
+
Raises:
|
743
|
+
Exception: If the modification fails
|
744
|
+
"""
|
745
|
+
try:
|
746
|
+
assessment = await unique_sdk.MessageAssessment.modify_async(
|
747
|
+
user_id=self.event.user_id,
|
748
|
+
company_id=self.event.company_id,
|
749
|
+
assistant_message_id=assistant_message_id,
|
750
|
+
status=status.name,
|
751
|
+
explanation=explanation,
|
752
|
+
label=label.name,
|
753
|
+
type=type.name,
|
754
|
+
)
|
755
|
+
return MessageAssessment(**assessment)
|
756
|
+
except Exception as e:
|
757
|
+
self.logger.error(f"Failed to modify message assessment: {e}")
|
758
|
+
raise e
|
@@ -51,6 +51,8 @@ class LanguageModelService(BaseService):
|
|
51
51
|
temperature (float): The temperature value. Defaults to 0.
|
52
52
|
timeout (int): The timeout value in milliseconds. Defaults to 240_000.
|
53
53
|
tools (Optional[list[LanguageModelTool]]): The tools to use. Defaults to None.
|
54
|
+
structured_output_model (Optional[Type[BaseModel]]): The structured output model. Defaults to None.
|
55
|
+
structured_output_enforce_schema (bool): Whether to enforce the schema. Defaults to False.
|
54
56
|
other_options (Optional[dict]): The other options to use. Defaults to None.
|
55
57
|
|
56
58
|
Returns:
|
@@ -82,8 +84,9 @@ class LanguageModelService(BaseService):
|
|
82
84
|
self.logger.error(f"Error completing: {e}")
|
83
85
|
raise e
|
84
86
|
|
87
|
+
@classmethod
|
85
88
|
async def complete_async_util(
|
86
|
-
|
89
|
+
cls,
|
87
90
|
company_id: str,
|
88
91
|
messages: LanguageModelMessages,
|
89
92
|
model_name: LanguageModelName | str,
|
@@ -110,6 +113,8 @@ class LanguageModelService(BaseService):
|
|
110
113
|
timeout (int): The timeout value in milliseconds for the request. Defaults to 240_000.
|
111
114
|
tools (Optional[list[LanguageModelTool]]): Optional list of tools to include in the request.
|
112
115
|
other_options (Optional[dict]): The other options to use. Defaults to None.
|
116
|
+
structured_output_model (Optional[Type[BaseModel]]): The structured output model. Defaults to None.
|
117
|
+
structured_output_enforce_schema (bool): Whether to enforce the schema. Defaults to False.
|
113
118
|
logger (Optional[logging.Logger], optional): The logger used to log errors. Defaults to the logger for the current module.
|
114
119
|
|
115
120
|
Returns:
|
@@ -118,7 +123,7 @@ class LanguageModelService(BaseService):
|
|
118
123
|
Raises:
|
119
124
|
Exception: If an error occurs during the request, an exception is raised and logged.
|
120
125
|
"""
|
121
|
-
options, model, messages_dict, _ =
|
126
|
+
options, model, messages_dict, _ = cls._prepare_completion_params_util(
|
122
127
|
messages=messages,
|
123
128
|
model_name=model_name,
|
124
129
|
temperature=temperature,
|
@@ -151,6 +156,8 @@ class LanguageModelService(BaseService):
|
|
151
156
|
temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
|
152
157
|
timeout: int = DEFAULT_COMPLETE_TIMEOUT,
|
153
158
|
tools: Optional[list[LanguageModelTool]] = None,
|
159
|
+
structured_output_model: Optional[Type[BaseModel]] = None,
|
160
|
+
structured_output_enforce_schema: bool = False,
|
154
161
|
other_options: Optional[dict] = None,
|
155
162
|
) -> LanguageModelResponse:
|
156
163
|
"""
|
@@ -166,6 +173,8 @@ class LanguageModelService(BaseService):
|
|
166
173
|
temperature (float): The temperature setting for the completion. Defaults to 0.0.
|
167
174
|
timeout (int): The timeout value in milliseconds for the request. Defaults to 240,000.
|
168
175
|
tools (Optional[list[LanguageModelTool]]): Optional list of tools to include in the request.
|
176
|
+
structured_output_model (Optional[Type[BaseModel]]): The structured output model. Defaults to None.
|
177
|
+
structured_output_enforce_schema (bool): Whether to enforce the schema. Defaults to False.
|
169
178
|
other_options (Optional[dict]): The other options to use. Defaults to None.
|
170
179
|
Returns:
|
171
180
|
LanguageModelResponse: The response object containing the completed result.
|
@@ -182,6 +191,8 @@ class LanguageModelService(BaseService):
|
|
182
191
|
tools=tools,
|
183
192
|
other_options=other_options,
|
184
193
|
logger=self.logger,
|
194
|
+
structured_output_model=structured_output_model,
|
195
|
+
structured_output_enforce_schema=structured_output_enforce_schema,
|
185
196
|
)
|
186
197
|
|
187
198
|
def stream_complete(
|
@@ -359,8 +370,9 @@ class LanguageModelService(BaseService):
|
|
359
370
|
}
|
360
371
|
return options
|
361
372
|
|
373
|
+
@classmethod
|
362
374
|
def _prepare_completion_params_util(
|
363
|
-
|
375
|
+
cls,
|
364
376
|
messages: LanguageModelMessages,
|
365
377
|
model_name: LanguageModelName | str,
|
366
378
|
temperature: float,
|
@@ -381,10 +393,10 @@ class LanguageModelService(BaseService):
|
|
381
393
|
- search_context (Optional[dict]): Processed content chunks if provided
|
382
394
|
"""
|
383
395
|
|
384
|
-
options =
|
396
|
+
options = cls._add_tools_to_options({}, tools)
|
385
397
|
|
386
398
|
if structured_output_model:
|
387
|
-
options =
|
399
|
+
options = cls._add_response_format_to_options(
|
388
400
|
options, structured_output_model, structured_output_enforce_schema
|
389
401
|
)
|
390
402
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: unique_toolkit
|
3
|
-
Version: 0.5.
|
3
|
+
Version: 0.5.52
|
4
4
|
Summary:
|
5
5
|
License: Proprietary
|
6
6
|
Author: Martin Fadler
|
@@ -55,8 +55,8 @@ The `unique_toolkit.app` module encompasses functions for initializing and secur
|
|
55
55
|
|
56
56
|
The `unique_toolkit.chat` module encompasses all chat related functionality.
|
57
57
|
|
58
|
-
- `service.py` comprises the ChatService and provides an interface to manage and load the chat history and interact with the chat ui, e.g., creating a new assistant message.
|
59
|
-
- `schemas.py` comprises all relevant schemas, e.g., ChatMessage, used in the ChatService.
|
58
|
+
- `service.py` comprises the ChatService and provides an interface to manage and load the chat history and interact with the chat ui, e.g., creating a new assistant message, modifying messages, and managing message assessments.
|
59
|
+
- `schemas.py` comprises all relevant schemas, e.g., ChatMessage, MessageAssessment, used in the ChatService.
|
60
60
|
- `utils.py` comprises utility functions to use and convert ChatMessage objects in assistants, e.g., convert_chat_history_to_injectable_string converts the chat history to a string that can be injected into a prompt.
|
61
61
|
|
62
62
|
## Content
|
@@ -100,10 +100,16 @@ All notable changes to this project will be documented in this file.
|
|
100
100
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
101
101
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
102
102
|
|
103
|
+
## [0.5.52] - 2025-02-01
|
104
|
+
- Add `MessageAssessment` schemas and functions to `ChatService` to handle message assessments.
|
105
|
+
- Fix `LanguageModelService.complete_async_util` to use the correct async method.
|
106
|
+
|
107
|
+
## [0.5.51] - 2025-01-30
|
108
|
+
- Add missing structured output arguments in complete_async
|
109
|
+
|
103
110
|
## [0.5.50] - 2025-01-30
|
104
111
|
- Add the possibility to define completion output structure through a pydantic class
|
105
112
|
|
106
|
-
|
107
113
|
## [0.5.49] - 2025-01-24
|
108
114
|
- Add `parsed` and `refusal` to `LanguageModelAssistantMessage` to support structured output
|
109
115
|
|
@@ -10,9 +10,9 @@ unique_toolkit/app/performance/async_tasks.py,sha256=H0l3OAcosLwNHZ8d2pd-Di4wHIX
|
|
10
10
|
unique_toolkit/app/performance/async_wrapper.py,sha256=yVVcRDkcdyfjsxro-N29SBvi-7773wnfDplef6-y8xw,1077
|
11
11
|
unique_toolkit/app/schemas.py,sha256=6RY7Ex-B3pOnFILlitHEi9sqJvupbpdxlN9xt33qRsM,1571
|
12
12
|
unique_toolkit/app/verification.py,sha256=mffa6wm0i4hJbwzofePrkaia46xumMzECwQ0T3eKAx0,1929
|
13
|
-
unique_toolkit/chat/__init__.py,sha256=
|
14
|
-
unique_toolkit/chat/schemas.py,sha256=
|
15
|
-
unique_toolkit/chat/service.py,sha256=
|
13
|
+
unique_toolkit/chat/__init__.py,sha256=4xS-Mcv7Oqdhprw1JEqD3nwGFflla4R2o7RNJyA5Wek,537
|
14
|
+
unique_toolkit/chat/schemas.py,sha256=pWEOkLgZn4LUriFAQeKFHDAqUe1vjl20LPsoM1tdIic,2227
|
15
|
+
unique_toolkit/chat/service.py,sha256=AQ61nrUBLTomBCzSmyzZ9257pRH666zKNDrtQHoPkrE,27851
|
16
16
|
unique_toolkit/chat/state.py,sha256=Cjgwv_2vhDFbV69xxsn7SefhaoIAEqLx3ferdVFCnOg,1445
|
17
17
|
unique_toolkit/chat/utils.py,sha256=ihm-wQykBWhB4liR3LnwPVPt_qGW6ETq21Mw4HY0THE,854
|
18
18
|
unique_toolkit/content/__init__.py,sha256=MSH2sxjQyKD2Sef92fzE5Dt9SihdzivB6yliSwJfTmQ,890
|
@@ -40,11 +40,11 @@ unique_toolkit/language_model/builder.py,sha256=nsRqWO_2dgFehK5CgtqR5aqXgYUU0QL6
|
|
40
40
|
unique_toolkit/language_model/infos.py,sha256=NgoV05ausVWMqrYqgH6i3s7tYG7mejupROIF_bwEGZo,13050
|
41
41
|
unique_toolkit/language_model/prompt.py,sha256=JSawaLjQg3VR-E2fK8engFyJnNdk21zaO8pPIodzN4Q,3991
|
42
42
|
unique_toolkit/language_model/schemas.py,sha256=87511yupvea-U6sfKWfelETevNMVPevhj7mEqX5FszU,7461
|
43
|
-
unique_toolkit/language_model/service.py,sha256=
|
43
|
+
unique_toolkit/language_model/service.py,sha256=m4B4YD4wxfU8HNo_stqbfnlKXziYBAwqtny4kRtywks,17837
|
44
44
|
unique_toolkit/language_model/utils.py,sha256=bPQ4l6_YO71w-zaIPanUUmtbXC1_hCvLK0tAFc3VCRc,1902
|
45
45
|
unique_toolkit/short_term_memory/schemas.py,sha256=OhfcXyF6ACdwIXW45sKzjtZX_gkcJs8FEZXcgQTNenw,1406
|
46
46
|
unique_toolkit/short_term_memory/service.py,sha256=Jd9P72-VvJy7hnqNrjmrmB5BHmsKuOpTiT0Jr-dBbsQ,1682
|
47
|
-
unique_toolkit-0.5.
|
48
|
-
unique_toolkit-0.5.
|
49
|
-
unique_toolkit-0.5.
|
50
|
-
unique_toolkit-0.5.
|
47
|
+
unique_toolkit-0.5.52.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
|
48
|
+
unique_toolkit-0.5.52.dist-info/METADATA,sha256=M7kVSW4aRX-04EGrhWt136ICM75ok4vFPkjBJyvkbZc,16293
|
49
|
+
unique_toolkit-0.5.52.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
50
|
+
unique_toolkit-0.5.52.dist-info/RECORD,,
|
File without changes
|
File without changes
|