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.
@@ -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,
@@ -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
@@ -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 ChatMessage, ChatMessageRole
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
- self,
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, _ = self._prepare_completion_params_util(
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
- self,
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 = self._add_tools_to_options({}, tools)
396
+ options = cls._add_tools_to_options({}, tools)
385
397
 
386
398
  if structured_output_model:
387
- options = self._add_response_format_to_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.50
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=1prdTVfLOf6NgU-Aa1VIO-XiR6OYuRm51LaVRfKDCqc,267
14
- unique_toolkit/chat/schemas.py,sha256=IHOnb3pWlRlSPoEUWBTl6LK8YeMdlg2iXi9ghyBeiLw,1495
15
- unique_toolkit/chat/service.py,sha256=lFcwCKHRHVLkMIO1cBHwH_Py0uZ4mmvgkUwQuZkpsxI,21438
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=jBHFeGtPbaOeVBxg4XBwzCLjpkIDDAx_9eW7X_fOibk,16900
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.50.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
48
- unique_toolkit-0.5.50.dist-info/METADATA,sha256=ybCuYkNYzgWuZhRbEf_vSlVG1zMXWLaAEH8Es53iy20,15931
49
- unique_toolkit-0.5.50.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
50
- unique_toolkit-0.5.50.dist-info/RECORD,,
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,,