unique_toolkit 0.7.25__py3-none-any.whl → 0.7.27__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/app/schemas.py +52 -8
- unique_toolkit/chat/functions.py +79 -4
- unique_toolkit/chat/service.py +60 -13
- unique_toolkit/content/functions.py +7 -6
- unique_toolkit/content/schemas.py +2 -2
- unique_toolkit/content/service.py +1 -1
- unique_toolkit/language_model/functions.py +142 -9
- unique_toolkit/language_model/reference.py +244 -0
- unique_toolkit/language_model/service.py +57 -1
- unique_toolkit/protocols/support.py +36 -2
- unique_toolkit/smart_rules/__init__.py +0 -0
- unique_toolkit/smart_rules/compile.py +301 -0
- {unique_toolkit-0.7.25.dist-info → unique_toolkit-0.7.27.dist-info}/METADATA +11 -1
- {unique_toolkit-0.7.25.dist-info → unique_toolkit-0.7.27.dist-info}/RECORD +16 -13
- {unique_toolkit-0.7.25.dist-info → unique_toolkit-0.7.27.dist-info}/LICENSE +0 -0
- {unique_toolkit-0.7.25.dist-info → unique_toolkit-0.7.27.dist-info}/WHEEL +0 -0
unique_toolkit/app/schemas.py
CHANGED
@@ -1,10 +1,14 @@
|
|
1
|
+
import json
|
1
2
|
from enum import StrEnum
|
3
|
+
from pathlib import Path
|
2
4
|
from typing import Any, Optional
|
3
5
|
|
4
6
|
from humps import camelize
|
5
|
-
from pydantic import BaseModel, ConfigDict, Field
|
7
|
+
from pydantic import BaseModel, ConfigDict, Field, field_validator
|
6
8
|
from typing_extensions import deprecated
|
7
9
|
|
10
|
+
from unique_toolkit.smart_rules.compile import UniqueQL, parse_uniqueql
|
11
|
+
|
8
12
|
# set config to convert camelCase to snake_case
|
9
13
|
model_config = ConfigDict(
|
10
14
|
alias_generator=camelize,
|
@@ -25,6 +29,14 @@ class BaseEvent(BaseModel):
|
|
25
29
|
user_id: str
|
26
30
|
company_id: str
|
27
31
|
|
32
|
+
@classmethod
|
33
|
+
def from_json_file(cls, file_path: Path) -> "BaseEvent":
|
34
|
+
if not file_path.exists():
|
35
|
+
raise FileNotFoundError(f"File not found: {file_path}")
|
36
|
+
with file_path.open("r", encoding="utf-8") as f:
|
37
|
+
data = json.load(f)
|
38
|
+
return cls.model_validate(data)
|
39
|
+
|
28
40
|
|
29
41
|
###
|
30
42
|
# ChatEvent schemas
|
@@ -95,15 +107,31 @@ class ChatEventPayload(BaseModel):
|
|
95
107
|
assistant_id: str
|
96
108
|
user_message: ChatEventUserMessage
|
97
109
|
assistant_message: ChatEventAssistantMessage
|
98
|
-
text:
|
99
|
-
additional_parameters:
|
100
|
-
user_metadata:
|
101
|
-
|
102
|
-
|
110
|
+
text: str | None = None
|
111
|
+
additional_parameters: ChatEventAdditionalParameters | None = None
|
112
|
+
user_metadata: dict[str, Any] | None = Field(
|
113
|
+
default_factory=dict,
|
114
|
+
)
|
115
|
+
tool_choices: list[str] = Field(
|
116
|
+
default_factory=list,
|
103
117
|
description="A list containing the tool names the user has chosen to be activated.",
|
104
118
|
)
|
105
|
-
tool_parameters:
|
106
|
-
|
119
|
+
tool_parameters: dict[str, Any] = Field(
|
120
|
+
default_factory=dict,
|
121
|
+
description="Parameters extracted from module selection function calling the tool.",
|
122
|
+
)
|
123
|
+
metadata_filter: dict[str, Any] = Field(
|
124
|
+
default_factory=dict,
|
125
|
+
description="Metadata filter compiled after module selection function calling and scope rules.",
|
126
|
+
)
|
127
|
+
raw_scope_rules: UniqueQL | None = Field(
|
128
|
+
default=None,
|
129
|
+
description="Raw UniqueQL rule that can be compiled to a metadata filter.",
|
130
|
+
)
|
131
|
+
|
132
|
+
@field_validator("raw_scope_rules", mode="before")
|
133
|
+
def validate_scope_rules(cls, value: dict[str, Any]) -> UniqueQL:
|
134
|
+
return parse_uniqueql(value)
|
107
135
|
|
108
136
|
|
109
137
|
@deprecated("""Use `ChatEventPayload` instead.
|
@@ -122,6 +150,14 @@ class ChatEvent(BaseEvent):
|
|
122
150
|
created_at: Optional[int] = None
|
123
151
|
version: Optional[str] = None
|
124
152
|
|
153
|
+
@classmethod
|
154
|
+
def from_json_file(cls, file_path: Path) -> "ChatEvent":
|
155
|
+
if not file_path.exists():
|
156
|
+
raise FileNotFoundError(f"File not found: {file_path}")
|
157
|
+
with file_path.open("r", encoding="utf-8") as f:
|
158
|
+
data = json.load(f)
|
159
|
+
return cls.model_validate(data)
|
160
|
+
|
125
161
|
|
126
162
|
@deprecated(
|
127
163
|
"""Use the more specific `ChatEvent` instead that has the same properties. \
|
@@ -132,3 +168,11 @@ class Event(ChatEvent):
|
|
132
168
|
# The below should only affect type hints
|
133
169
|
# event: EventName T
|
134
170
|
# payload: EventPayload
|
171
|
+
|
172
|
+
@classmethod
|
173
|
+
def from_json_file(cls, file_path: Path) -> "Event":
|
174
|
+
if not file_path.exists():
|
175
|
+
raise FileNotFoundError(f"File not found: {file_path}")
|
176
|
+
with file_path.open("r", encoding="utf-8") as f:
|
177
|
+
data = json.load(f)
|
178
|
+
return cls.model_validate(data)
|
unique_toolkit/chat/functions.py
CHANGED
@@ -3,6 +3,7 @@ import re
|
|
3
3
|
from typing import Any, Dict, List, cast
|
4
4
|
|
5
5
|
import unique_sdk
|
6
|
+
from typing_extensions import deprecated
|
6
7
|
from unique_sdk._list_object import ListObject
|
7
8
|
|
8
9
|
from unique_toolkit._common import _time_utils
|
@@ -673,6 +674,7 @@ async def modify_message_assessment_async(
|
|
673
674
|
raise e
|
674
675
|
|
675
676
|
|
677
|
+
@deprecated("Use stream_complete_with_references instead")
|
676
678
|
def stream_complete_to_chat(
|
677
679
|
company_id: str,
|
678
680
|
user_id: str,
|
@@ -682,7 +684,43 @@ def stream_complete_to_chat(
|
|
682
684
|
assistant_id: str,
|
683
685
|
messages: LanguageModelMessages,
|
684
686
|
model_name: LanguageModelName | str,
|
685
|
-
content_chunks: list[ContentChunk] =
|
687
|
+
content_chunks: list[ContentChunk] | None = None,
|
688
|
+
debug_info: dict = {},
|
689
|
+
temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
|
690
|
+
timeout: int = DEFAULT_COMPLETE_TIMEOUT,
|
691
|
+
tools: list[LanguageModelTool | LanguageModelToolDescription] | None = None,
|
692
|
+
start_text: str | None = None,
|
693
|
+
other_options: dict | None = None,
|
694
|
+
) -> LanguageModelStreamResponse:
|
695
|
+
return stream_complete_with_references(
|
696
|
+
company_id=company_id,
|
697
|
+
user_id=user_id,
|
698
|
+
assistant_message_id=assistant_message_id,
|
699
|
+
user_message_id=user_message_id,
|
700
|
+
chat_id=chat_id,
|
701
|
+
assistant_id=assistant_id,
|
702
|
+
messages=messages,
|
703
|
+
model_name=model_name,
|
704
|
+
content_chunks=content_chunks,
|
705
|
+
debug_info=debug_info,
|
706
|
+
temperature=temperature,
|
707
|
+
timeout=timeout,
|
708
|
+
tools=tools,
|
709
|
+
start_text=start_text,
|
710
|
+
other_options=other_options,
|
711
|
+
)
|
712
|
+
|
713
|
+
|
714
|
+
def stream_complete_with_references(
|
715
|
+
company_id: str,
|
716
|
+
user_id: str,
|
717
|
+
assistant_message_id: str,
|
718
|
+
user_message_id: str,
|
719
|
+
chat_id: str,
|
720
|
+
assistant_id: str,
|
721
|
+
messages: LanguageModelMessages,
|
722
|
+
model_name: LanguageModelName | str,
|
723
|
+
content_chunks: list[ContentChunk] | None = None,
|
686
724
|
debug_info: dict = {},
|
687
725
|
temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
|
688
726
|
timeout: int = DEFAULT_COMPLETE_TIMEOUT,
|
@@ -719,7 +757,7 @@ def stream_complete_to_chat(
|
|
719
757
|
temperature=temperature,
|
720
758
|
tools=tools,
|
721
759
|
other_options=other_options,
|
722
|
-
content_chunks=content_chunks,
|
760
|
+
content_chunks=content_chunks or [],
|
723
761
|
)
|
724
762
|
|
725
763
|
try:
|
@@ -747,6 +785,7 @@ def stream_complete_to_chat(
|
|
747
785
|
raise e
|
748
786
|
|
749
787
|
|
788
|
+
@deprecated("Use stream_complete_with_references_async instead")
|
750
789
|
async def stream_complete_to_chat_async(
|
751
790
|
company_id: str,
|
752
791
|
user_id: str,
|
@@ -756,7 +795,43 @@ async def stream_complete_to_chat_async(
|
|
756
795
|
assistant_id: str,
|
757
796
|
messages: LanguageModelMessages,
|
758
797
|
model_name: LanguageModelName | str,
|
759
|
-
content_chunks: list[ContentChunk] =
|
798
|
+
content_chunks: list[ContentChunk] | None = None,
|
799
|
+
debug_info: dict = {},
|
800
|
+
temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
|
801
|
+
timeout: int = DEFAULT_COMPLETE_TIMEOUT,
|
802
|
+
tools: list[LanguageModelTool | LanguageModelToolDescription] | None = None,
|
803
|
+
start_text: str | None = None,
|
804
|
+
other_options: dict | None = None,
|
805
|
+
) -> LanguageModelStreamResponse:
|
806
|
+
return await stream_complete_with_references_async(
|
807
|
+
company_id=company_id,
|
808
|
+
user_id=user_id,
|
809
|
+
assistant_message_id=assistant_message_id,
|
810
|
+
user_message_id=user_message_id,
|
811
|
+
chat_id=chat_id,
|
812
|
+
assistant_id=assistant_id,
|
813
|
+
messages=messages,
|
814
|
+
model_name=model_name,
|
815
|
+
content_chunks=content_chunks,
|
816
|
+
debug_info=debug_info,
|
817
|
+
temperature=temperature,
|
818
|
+
timeout=timeout,
|
819
|
+
tools=tools,
|
820
|
+
start_text=start_text,
|
821
|
+
other_options=other_options,
|
822
|
+
)
|
823
|
+
|
824
|
+
|
825
|
+
async def stream_complete_with_references_async(
|
826
|
+
company_id: str,
|
827
|
+
user_id: str,
|
828
|
+
assistant_message_id: str,
|
829
|
+
user_message_id: str,
|
830
|
+
chat_id: str,
|
831
|
+
assistant_id: str,
|
832
|
+
messages: LanguageModelMessages,
|
833
|
+
model_name: LanguageModelName | str,
|
834
|
+
content_chunks: list[ContentChunk] | None = None,
|
760
835
|
debug_info: dict = {},
|
761
836
|
temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
|
762
837
|
timeout: int = DEFAULT_COMPLETE_TIMEOUT,
|
@@ -778,7 +853,7 @@ async def stream_complete_to_chat_async(
|
|
778
853
|
temperature=temperature,
|
779
854
|
tools=tools,
|
780
855
|
other_options=other_options,
|
781
|
-
content_chunks=content_chunks,
|
856
|
+
content_chunks=content_chunks or [],
|
782
857
|
)
|
783
858
|
|
784
859
|
try:
|
unique_toolkit/chat/service.py
CHANGED
@@ -48,8 +48,8 @@ from unique_toolkit.language_model.schemas import (
|
|
48
48
|
)
|
49
49
|
|
50
50
|
from .functions import (
|
51
|
-
|
52
|
-
|
51
|
+
stream_complete_with_references,
|
52
|
+
stream_complete_with_references_async,
|
53
53
|
)
|
54
54
|
|
55
55
|
logger = logging.getLogger(f"toolkit.{DOMAIN_NAME}.{__name__}")
|
@@ -1084,11 +1084,36 @@ class ChatService:
|
|
1084
1084
|
label=label,
|
1085
1085
|
)
|
1086
1086
|
|
1087
|
+
@deprecated("Use complete_with_references instead")
|
1087
1088
|
def stream_complete(
|
1088
1089
|
self,
|
1089
1090
|
messages: LanguageModelMessages,
|
1090
1091
|
model_name: LanguageModelName | str,
|
1091
|
-
content_chunks: list[ContentChunk] =
|
1092
|
+
content_chunks: list[ContentChunk] | None = None,
|
1093
|
+
debug_info: dict = {},
|
1094
|
+
temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
|
1095
|
+
timeout: int = DEFAULT_COMPLETE_TIMEOUT,
|
1096
|
+
tools: Optional[list[LanguageModelTool | LanguageModelToolDescription]] = None,
|
1097
|
+
start_text: Optional[str] = None,
|
1098
|
+
other_options: Optional[dict] = None,
|
1099
|
+
) -> LanguageModelStreamResponse:
|
1100
|
+
return self.complete_with_references(
|
1101
|
+
messages=messages,
|
1102
|
+
model_name=model_name,
|
1103
|
+
content_chunks=content_chunks,
|
1104
|
+
debug_info=debug_info,
|
1105
|
+
temperature=temperature,
|
1106
|
+
timeout=timeout,
|
1107
|
+
tools=tools,
|
1108
|
+
start_text=start_text,
|
1109
|
+
other_options=other_options,
|
1110
|
+
)
|
1111
|
+
|
1112
|
+
def complete_with_references(
|
1113
|
+
self,
|
1114
|
+
messages: LanguageModelMessages,
|
1115
|
+
model_name: LanguageModelName | str,
|
1116
|
+
content_chunks: list[ContentChunk] | None = None,
|
1092
1117
|
debug_info: dict = {},
|
1093
1118
|
temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
|
1094
1119
|
timeout: int = DEFAULT_COMPLETE_TIMEOUT,
|
@@ -1117,7 +1142,7 @@ class ChatService:
|
|
1117
1142
|
]
|
1118
1143
|
)
|
1119
1144
|
|
1120
|
-
return
|
1145
|
+
return stream_complete_with_references(
|
1121
1146
|
company_id=company_id,
|
1122
1147
|
user_id=user_id,
|
1123
1148
|
assistant_message_id=assistant_message_id,
|
@@ -1139,7 +1164,7 @@ class ChatService:
|
|
1139
1164
|
self,
|
1140
1165
|
messages: LanguageModelMessages,
|
1141
1166
|
model_name: LanguageModelName | str,
|
1142
|
-
content_chunks: list[ContentChunk] =
|
1167
|
+
content_chunks: list[ContentChunk] | None = None,
|
1143
1168
|
debug_info: dict = {},
|
1144
1169
|
temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
|
1145
1170
|
timeout: int = DEFAULT_COMPLETE_TIMEOUT,
|
@@ -1147,7 +1172,7 @@ class ChatService:
|
|
1147
1172
|
start_text: Optional[str] = None,
|
1148
1173
|
other_options: Optional[dict] = None,
|
1149
1174
|
) -> LanguageModelResponse:
|
1150
|
-
response = self.
|
1175
|
+
response = self.complete_with_references(
|
1151
1176
|
messages=messages,
|
1152
1177
|
model_name=model_name,
|
1153
1178
|
content_chunks=content_chunks,
|
@@ -1161,11 +1186,12 @@ class ChatService:
|
|
1161
1186
|
|
1162
1187
|
return LanguageModelResponse.from_stream_response(response)
|
1163
1188
|
|
1189
|
+
@deprecated("use complete_with_references_async instead.")
|
1164
1190
|
async def stream_complete_async(
|
1165
1191
|
self,
|
1166
1192
|
messages: LanguageModelMessages,
|
1167
1193
|
model_name: LanguageModelName | str,
|
1168
|
-
content_chunks: list[ContentChunk] =
|
1194
|
+
content_chunks: list[ContentChunk] | None = None,
|
1169
1195
|
debug_info: dict = {},
|
1170
1196
|
temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
|
1171
1197
|
timeout: int = DEFAULT_COMPLETE_TIMEOUT,
|
@@ -1173,10 +1199,31 @@ class ChatService:
|
|
1173
1199
|
start_text: Optional[str] = None,
|
1174
1200
|
other_options: Optional[dict] = None,
|
1175
1201
|
) -> LanguageModelStreamResponse:
|
1176
|
-
"""
|
1177
|
-
|
1178
|
-
|
1202
|
+
"""Stream a completion in the chat session asynchronously."""
|
1203
|
+
return await self.complete_with_references_async(
|
1204
|
+
messages=messages,
|
1205
|
+
model_name=model_name,
|
1206
|
+
content_chunks=content_chunks,
|
1207
|
+
debug_info=debug_info,
|
1208
|
+
temperature=temperature,
|
1209
|
+
timeout=timeout,
|
1210
|
+
tools=tools,
|
1211
|
+
start_text=start_text,
|
1212
|
+
other_options=other_options,
|
1213
|
+
)
|
1179
1214
|
|
1215
|
+
async def complete_with_references_async(
|
1216
|
+
self,
|
1217
|
+
messages: LanguageModelMessages,
|
1218
|
+
model_name: LanguageModelName | str,
|
1219
|
+
content_chunks: list[ContentChunk] | None = None,
|
1220
|
+
debug_info: dict = {},
|
1221
|
+
temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
|
1222
|
+
timeout: int = DEFAULT_COMPLETE_TIMEOUT,
|
1223
|
+
tools: Optional[list[LanguageModelTool | LanguageModelToolDescription]] = None,
|
1224
|
+
start_text: Optional[str] = None,
|
1225
|
+
other_options: Optional[dict] = None,
|
1226
|
+
) -> LanguageModelStreamResponse:
|
1180
1227
|
[
|
1181
1228
|
company_id,
|
1182
1229
|
user_id,
|
@@ -1195,7 +1242,7 @@ class ChatService:
|
|
1195
1242
|
]
|
1196
1243
|
)
|
1197
1244
|
|
1198
|
-
return await
|
1245
|
+
return await stream_complete_with_references_async(
|
1199
1246
|
company_id=company_id,
|
1200
1247
|
user_id=user_id,
|
1201
1248
|
assistant_message_id=assistant_message_id,
|
@@ -1217,7 +1264,7 @@ class ChatService:
|
|
1217
1264
|
self,
|
1218
1265
|
messages: LanguageModelMessages,
|
1219
1266
|
model_name: LanguageModelName | str,
|
1220
|
-
content_chunks: list[ContentChunk]
|
1267
|
+
content_chunks: list[ContentChunk] | None,
|
1221
1268
|
debug_info: dict = {},
|
1222
1269
|
temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
|
1223
1270
|
timeout: int = DEFAULT_COMPLETE_TIMEOUT,
|
@@ -1225,7 +1272,7 @@ class ChatService:
|
|
1225
1272
|
start_text: Optional[str] = None,
|
1226
1273
|
other_options: Optional[dict] = None,
|
1227
1274
|
) -> LanguageModelResponse:
|
1228
|
-
response = self.
|
1275
|
+
response = self.complete_with_references_async(
|
1229
1276
|
messages=messages,
|
1230
1277
|
model_name=model_name,
|
1231
1278
|
content_chunks=content_chunks,
|
@@ -3,6 +3,7 @@ import os
|
|
3
3
|
import re
|
4
4
|
import tempfile
|
5
5
|
from pathlib import Path
|
6
|
+
from typing import Any
|
6
7
|
|
7
8
|
import requests
|
8
9
|
import unique_sdk
|
@@ -214,7 +215,7 @@ def upload_content_from_bytes(
|
|
214
215
|
chat_id: str | None = None,
|
215
216
|
skip_ingestion: bool = False,
|
216
217
|
ingestion_config: unique_sdk.Content.IngestionConfig | None = None,
|
217
|
-
metadata: dict[str,
|
218
|
+
metadata: dict[str, Any] | None = None,
|
218
219
|
):
|
219
220
|
"""
|
220
221
|
Uploads content to the knowledge base.
|
@@ -229,7 +230,7 @@ def upload_content_from_bytes(
|
|
229
230
|
chat_id (str | None): The chat ID. Defaults to None.
|
230
231
|
skip_ingestion (bool): Whether to skip ingestion. Defaults to False.
|
231
232
|
ingestion_config (unique_sdk.Content.IngestionConfig | None): The ingestion configuration. Defaults to None.
|
232
|
-
metadata ( dict[str,
|
233
|
+
metadata ( dict[str, Any] | None): The metadata for the content. Defaults to None.
|
233
234
|
|
234
235
|
Returns:
|
235
236
|
Content: The uploaded content.
|
@@ -263,7 +264,7 @@ def upload_content(
|
|
263
264
|
chat_id: str | None = None,
|
264
265
|
skip_ingestion: bool = False,
|
265
266
|
ingestion_config: unique_sdk.Content.IngestionConfig | None = None,
|
266
|
-
metadata: dict[str,
|
267
|
+
metadata: dict[str, Any] | None = None,
|
267
268
|
):
|
268
269
|
"""
|
269
270
|
Uploads content to the knowledge base.
|
@@ -278,7 +279,7 @@ def upload_content(
|
|
278
279
|
chat_id (str | None): The chat ID. Defaults to None.
|
279
280
|
skip_ingestion (bool): Whether to skip ingestion. Defaults to False.
|
280
281
|
ingestion_config (unique_sdk.Content.IngestionConfig | None): The ingestion configuration. Defaults to None.
|
281
|
-
metadata ( dict[str,
|
282
|
+
metadata ( dict[str, Any] | None): The metadata for the content. Defaults to None.
|
282
283
|
|
283
284
|
Returns:
|
284
285
|
Content: The uploaded content.
|
@@ -312,7 +313,7 @@ def _trigger_upload_content(
|
|
312
313
|
chat_id: str | None = None,
|
313
314
|
skip_ingestion: bool = False,
|
314
315
|
ingestion_config: unique_sdk.Content.IngestionConfig | None = None,
|
315
|
-
metadata: dict[str,
|
316
|
+
metadata: dict[str, Any] | None = None,
|
316
317
|
):
|
317
318
|
"""
|
318
319
|
Uploads content to the knowledge base.
|
@@ -327,7 +328,7 @@ def _trigger_upload_content(
|
|
327
328
|
chat_id (str | None): The chat ID. Defaults to None.
|
328
329
|
skip_ingestion (bool): Whether to skip ingestion. Defaults to False.
|
329
330
|
ingestion_config (unique_sdk.Content.IngestionConfig | None): The ingestion configuration. Defaults to None.
|
330
|
-
metadata (dict[str,
|
331
|
+
metadata (dict[str, Any] | None): The metadata for the content. Defaults to None.
|
331
332
|
|
332
333
|
Returns:
|
333
334
|
Content: The uploaded content.
|
@@ -1,6 +1,6 @@
|
|
1
1
|
from datetime import datetime
|
2
2
|
from enum import StrEnum
|
3
|
-
from typing import Optional
|
3
|
+
from typing import Any, Optional
|
4
4
|
|
5
5
|
from humps import camelize
|
6
6
|
from pydantic import BaseModel, ConfigDict, Field
|
@@ -54,7 +54,7 @@ class Content(BaseModel):
|
|
54
54
|
read_url: str | None = None
|
55
55
|
created_at: datetime | None = None
|
56
56
|
updated_at: datetime | None = None
|
57
|
-
metadata: dict[str,
|
57
|
+
metadata: dict[str, Any] | None = None
|
58
58
|
ingestion_config: dict | None = None
|
59
59
|
|
60
60
|
|
@@ -422,7 +422,7 @@ class ContentService:
|
|
422
422
|
chat_id (str | None): The chat ID. Defaults to None.
|
423
423
|
skip_ingestion (bool): Whether to skip ingestion. Defaults to False.
|
424
424
|
ingestion_config (unique_sdk.Content.IngestionConfig | None): The ingestion configuration. Defaults to None.
|
425
|
-
metadata (dict[str,
|
425
|
+
metadata (dict[str, Any] | None): The metadata to associate with the content. Defaults to None.
|
426
426
|
|
427
427
|
Returns:
|
428
428
|
Content: The uploaded content.
|
@@ -1,23 +1,33 @@
|
|
1
|
+
import copy
|
1
2
|
import logging
|
2
|
-
from
|
3
|
+
from datetime import datetime, timezone
|
4
|
+
from typing import Any, cast
|
3
5
|
|
4
6
|
import unique_sdk
|
5
7
|
from pydantic import BaseModel
|
6
8
|
|
9
|
+
from unique_toolkit.chat.schemas import ChatMessage, ChatMessageRole
|
7
10
|
from unique_toolkit.content.schemas import ContentChunk
|
8
11
|
from unique_toolkit.evaluators import DOMAIN_NAME
|
9
|
-
|
10
|
-
|
11
|
-
DEFAULT_COMPLETE_TEMPERATURE,
|
12
|
-
DEFAULT_COMPLETE_TIMEOUT,
|
13
|
-
)
|
14
|
-
from .infos import LanguageModelName
|
15
|
-
from .schemas import (
|
12
|
+
from unique_toolkit.language_model import (
|
13
|
+
LanguageModelMessageRole,
|
16
14
|
LanguageModelMessages,
|
17
15
|
LanguageModelResponse,
|
16
|
+
LanguageModelStreamResponse,
|
17
|
+
LanguageModelStreamResponseMessage,
|
18
18
|
LanguageModelTool,
|
19
19
|
LanguageModelToolDescription,
|
20
20
|
)
|
21
|
+
from unique_toolkit.language_model.infos import LanguageModelName
|
22
|
+
from unique_toolkit.language_model.reference import (
|
23
|
+
PotentialReference,
|
24
|
+
add_references_to_message,
|
25
|
+
)
|
26
|
+
|
27
|
+
from .constants import (
|
28
|
+
DEFAULT_COMPLETE_TEMPERATURE,
|
29
|
+
DEFAULT_COMPLETE_TIMEOUT,
|
30
|
+
)
|
21
31
|
|
22
32
|
logger = logging.getLogger(f"toolkit.{DOMAIN_NAME}.{__name__}")
|
23
33
|
|
@@ -36,6 +46,7 @@ def complete(
|
|
36
46
|
"""Call the completion endpoint synchronously without streaming the response.
|
37
47
|
|
38
48
|
Args:
|
49
|
+
----
|
39
50
|
company_id (str): The company ID associated with the request.
|
40
51
|
messages (LanguageModelMessages): The messages to complete.
|
41
52
|
model_name (LanguageModelName | str): The model name to use for the completion.
|
@@ -45,6 +56,7 @@ def complete(
|
|
45
56
|
other_options (Optional[dict]): Additional options to use. Defaults to None.
|
46
57
|
|
47
58
|
Returns:
|
59
|
+
-------
|
48
60
|
LanguageModelResponse: The response object containing the completed result.
|
49
61
|
|
50
62
|
"""
|
@@ -93,6 +105,7 @@ async def complete_async(
|
|
93
105
|
the completed result.
|
94
106
|
|
95
107
|
Args:
|
108
|
+
----
|
96
109
|
company_id (str): The company ID associated with the request.
|
97
110
|
messages (LanguageModelMessages): The messages to complete.
|
98
111
|
model_name (LanguageModelName | str): The model name to use for the completion.
|
@@ -102,9 +115,11 @@ async def complete_async(
|
|
102
115
|
other_options (Optional[dict]): The other options to use. Defaults to None.
|
103
116
|
|
104
117
|
Returns:
|
118
|
+
-------
|
105
119
|
LanguageModelResponse: The response object containing the completed result.
|
106
120
|
|
107
121
|
Raises:
|
122
|
+
------
|
108
123
|
Exception: If an error occurs during the request, an exception is raised
|
109
124
|
and logged.
|
110
125
|
|
@@ -198,7 +213,8 @@ def _prepare_completion_params_util(
|
|
198
213
|
) -> tuple[dict, str, dict, dict | None]:
|
199
214
|
"""Prepare common parameters for completion requests.
|
200
215
|
|
201
|
-
Returns
|
216
|
+
Returns
|
217
|
+
-------
|
202
218
|
tuple containing:
|
203
219
|
- options (dict): Combined options including tools and temperature
|
204
220
|
- model (str): Resolved model name
|
@@ -232,3 +248,120 @@ def _prepare_completion_params_util(
|
|
232
248
|
)
|
233
249
|
|
234
250
|
return options, model, messages_dict, search_context
|
251
|
+
|
252
|
+
|
253
|
+
def complete_with_references(
|
254
|
+
company_id: str,
|
255
|
+
messages: LanguageModelMessages,
|
256
|
+
model_name: LanguageModelName | str,
|
257
|
+
content_chunks: list[ContentChunk] | None = None,
|
258
|
+
debug_dict: dict = {},
|
259
|
+
temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
|
260
|
+
timeout: int = DEFAULT_COMPLETE_TIMEOUT,
|
261
|
+
tools: list[LanguageModelTool | LanguageModelToolDescription] | None = None,
|
262
|
+
start_text: str | None = None,
|
263
|
+
other_options: dict[str, Any] | None = None,
|
264
|
+
) -> LanguageModelStreamResponse:
|
265
|
+
# Use toolkit language model functions for chat completion
|
266
|
+
response = complete(
|
267
|
+
company_id=company_id,
|
268
|
+
model_name=model_name,
|
269
|
+
messages=messages,
|
270
|
+
temperature=temperature,
|
271
|
+
timeout=timeout,
|
272
|
+
tools=tools,
|
273
|
+
other_options=other_options,
|
274
|
+
)
|
275
|
+
|
276
|
+
return _create_language_model_stream_response_with_references(
|
277
|
+
response=response,
|
278
|
+
content_chunks=content_chunks,
|
279
|
+
start_text=start_text,
|
280
|
+
)
|
281
|
+
|
282
|
+
|
283
|
+
async def complete_with_references_async(
|
284
|
+
company_id: str,
|
285
|
+
messages: LanguageModelMessages,
|
286
|
+
model_name: LanguageModelName | str,
|
287
|
+
content_chunks: list[ContentChunk] | None = None,
|
288
|
+
debug_dict: dict = {},
|
289
|
+
temperature: float = DEFAULT_COMPLETE_TEMPERATURE,
|
290
|
+
timeout: int = DEFAULT_COMPLETE_TIMEOUT,
|
291
|
+
tools: list[LanguageModelTool | LanguageModelToolDescription] | None = None,
|
292
|
+
start_text: str | None = None,
|
293
|
+
other_options: dict[str, Any] | None = None,
|
294
|
+
) -> LanguageModelStreamResponse:
|
295
|
+
# Use toolkit language model functions for chat completion
|
296
|
+
response = await complete_async(
|
297
|
+
company_id=company_id,
|
298
|
+
model_name=model_name,
|
299
|
+
messages=messages,
|
300
|
+
temperature=temperature,
|
301
|
+
timeout=timeout,
|
302
|
+
tools=tools,
|
303
|
+
other_options=other_options,
|
304
|
+
)
|
305
|
+
|
306
|
+
return _create_language_model_stream_response_with_references(
|
307
|
+
response=response,
|
308
|
+
content_chunks=content_chunks,
|
309
|
+
start_text=start_text,
|
310
|
+
)
|
311
|
+
|
312
|
+
|
313
|
+
def _create_language_model_stream_response_with_references(
|
314
|
+
response: LanguageModelResponse,
|
315
|
+
content_chunks: list[ContentChunk] | None = None,
|
316
|
+
start_text: str | None = None,
|
317
|
+
):
|
318
|
+
content = response.choices[0].message.content
|
319
|
+
content_chunks = content_chunks or []
|
320
|
+
|
321
|
+
if content is None:
|
322
|
+
raise ValueError("Content is None, which is not supported")
|
323
|
+
elif isinstance(content, list):
|
324
|
+
raise ValueError("Content is a list, which is not supported")
|
325
|
+
else:
|
326
|
+
content = start_text or "" + str(content)
|
327
|
+
|
328
|
+
message = ChatMessage(
|
329
|
+
id="msg_unknown",
|
330
|
+
text=copy.deepcopy(content),
|
331
|
+
role=ChatMessageRole.ASSISTANT,
|
332
|
+
created_at=datetime.now(timezone.utc),
|
333
|
+
chat_id="chat_unknown",
|
334
|
+
)
|
335
|
+
|
336
|
+
search_context = [
|
337
|
+
PotentialReference(
|
338
|
+
id=source.id,
|
339
|
+
chunk_id=source.id,
|
340
|
+
title=source.title,
|
341
|
+
key=source.key or "",
|
342
|
+
url=source.url,
|
343
|
+
)
|
344
|
+
for source in content_chunks
|
345
|
+
]
|
346
|
+
|
347
|
+
message, __ = add_references_to_message(
|
348
|
+
message=message,
|
349
|
+
search_context=search_context,
|
350
|
+
)
|
351
|
+
|
352
|
+
stream_response_message = LanguageModelStreamResponseMessage(
|
353
|
+
id="stream_unknown",
|
354
|
+
previous_message_id=None,
|
355
|
+
role=LanguageModelMessageRole.ASSISTANT,
|
356
|
+
text=message.content or "",
|
357
|
+
original_text=content,
|
358
|
+
references=[u.model_dump() for u in message.references or []],
|
359
|
+
)
|
360
|
+
|
361
|
+
tool_calls = [r.function for r in response.choices[0].message.tool_calls or []]
|
362
|
+
tool_calls = tool_calls if len(tool_calls) > 0 else None
|
363
|
+
|
364
|
+
return LanguageModelStreamResponse(
|
365
|
+
message=stream_response_message,
|
366
|
+
tool_calls=tool_calls,
|
367
|
+
)
|