unique_toolkit 0.0.1__py3-none-any.whl → 0.5.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/__init__.py +0 -3
- unique_toolkit/{observability/log_config.py → app/init_logging.py} +10 -10
- unique_toolkit/app/init_sdk.py +41 -0
- unique_toolkit/{performance → app/performance}/async_executor.py +44 -17
- unique_toolkit/app/performance/async_wrapper.py +28 -0
- unique_toolkit/{event/schema.py → app/schemas.py} +17 -10
- unique_toolkit/app/verification.py +58 -0
- unique_toolkit/chat/schemas.py +30 -0
- unique_toolkit/chat/service.py +285 -87
- unique_toolkit/chat/state.py +22 -10
- unique_toolkit/chat/utils.py +25 -0
- unique_toolkit/content/schemas.py +90 -0
- unique_toolkit/content/service.py +356 -0
- unique_toolkit/content/utils.py +188 -0
- unique_toolkit/embedding/schemas.py +5 -0
- unique_toolkit/embedding/service.py +89 -0
- unique_toolkit/language_model/infos.py +305 -0
- unique_toolkit/language_model/schemas.py +168 -0
- unique_toolkit/language_model/service.py +261 -0
- unique_toolkit/language_model/utils.py +44 -0
- {unique_toolkit-0.0.1.dist-info → unique_toolkit-0.5.0.dist-info}/LICENSE +1 -1
- unique_toolkit-0.5.0.dist-info/METADATA +135 -0
- unique_toolkit-0.5.0.dist-info/RECORD +24 -0
- unique_toolkit/chat/__init__.py +0 -3
- unique_toolkit/chat/messages.py +0 -24
- unique_toolkit/event/__init__.py +0 -1
- unique_toolkit/event/constants.py +0 -1
- unique_toolkit/llm/__init__.py +0 -2
- unique_toolkit/llm/json_parser.py +0 -21
- unique_toolkit/llm/models.py +0 -37
- unique_toolkit/llm/service.py +0 -163
- unique_toolkit/performance/__init__.py +0 -1
- unique_toolkit/performance/async_wrapper.py +0 -13
- unique_toolkit/sdk/init.py +0 -19
- unique_toolkit/search/service.py +0 -118
- unique_toolkit/security/verify.py +0 -29
- unique_toolkit-0.0.1.dist-info/METADATA +0 -33
- unique_toolkit-0.0.1.dist-info/RECORD +0 -23
- {unique_toolkit-0.0.1.dist-info → unique_toolkit-0.5.0.dist-info}/WHEEL +0 -0
unique_toolkit/llm/service.py
DELETED
@@ -1,163 +0,0 @@
|
|
1
|
-
import unique_sdk
|
2
|
-
|
3
|
-
from unique_toolkit.chat.state import ChatState
|
4
|
-
from unique_toolkit.performance.async_wrapper import to_async
|
5
|
-
|
6
|
-
from .models import LLMModelName
|
7
|
-
|
8
|
-
|
9
|
-
class LLMService:
|
10
|
-
def __init__(self, state: ChatState):
|
11
|
-
self.state = state
|
12
|
-
|
13
|
-
def stream_complete(
|
14
|
-
self,
|
15
|
-
*,
|
16
|
-
messages: list,
|
17
|
-
model_name: LLMModelName,
|
18
|
-
search_contexts: list = [],
|
19
|
-
debug_info: dict = {},
|
20
|
-
timeout: int = 100_000,
|
21
|
-
temperature: float = 0.25,
|
22
|
-
):
|
23
|
-
"""
|
24
|
-
Streams a completion in the chat session synchronously.
|
25
|
-
|
26
|
-
Args:
|
27
|
-
messages (list): The messages to stream.
|
28
|
-
search_contexts (list): The search context.
|
29
|
-
model_name (LLMModelName): The language model to use for the completion.
|
30
|
-
debug_info (dict): The debug information.
|
31
|
-
timeout (int, optional): The timeout value in milliseconds. Defaults to 100_000.
|
32
|
-
temperature (float, optional): The temperature value for the completion. Defaults to 0.25.
|
33
|
-
|
34
|
-
Returns:
|
35
|
-
A generator yielding streamed completion chunks.
|
36
|
-
"""
|
37
|
-
return self._trigger_stream_complete(
|
38
|
-
messages,
|
39
|
-
search_contexts,
|
40
|
-
model_name.name,
|
41
|
-
debug_info,
|
42
|
-
timeout,
|
43
|
-
temperature,
|
44
|
-
)
|
45
|
-
|
46
|
-
@to_async
|
47
|
-
def async_stream_complete(
|
48
|
-
self,
|
49
|
-
*,
|
50
|
-
messages: list,
|
51
|
-
model_name: LLMModelName,
|
52
|
-
search_contexts: list = [],
|
53
|
-
debug_info: dict = {},
|
54
|
-
timeout: int = 100_000,
|
55
|
-
temperature: float = 0.25,
|
56
|
-
):
|
57
|
-
"""
|
58
|
-
Streams a completion in the chat session asynchronously.
|
59
|
-
|
60
|
-
Args:
|
61
|
-
messages (list[dict[str, str]]): The messages to stream.
|
62
|
-
search_contexts (list): The search context.
|
63
|
-
debug_info (dict): The debug information.
|
64
|
-
model_name (LLMModelName): The language model to use for the completion.
|
65
|
-
timeout (int, optional): The timeout value in milliseconds. Defaults to 100_000.
|
66
|
-
temperature (float, optional): The temperature value for the completion. Defaults to 0.25.
|
67
|
-
|
68
|
-
Returns:
|
69
|
-
A generator yielding streamed completion chunks.
|
70
|
-
"""
|
71
|
-
return self._trigger_stream_complete(
|
72
|
-
messages, search_contexts, model_name, debug_info, timeout, temperature
|
73
|
-
)
|
74
|
-
|
75
|
-
def complete(
|
76
|
-
self,
|
77
|
-
*,
|
78
|
-
messages: list,
|
79
|
-
model_name: LLMModelName,
|
80
|
-
temperature: float = 0,
|
81
|
-
timeout: int = 240000,
|
82
|
-
) -> str:
|
83
|
-
"""
|
84
|
-
Calls the completion endpoint synchronously without streaming the response.
|
85
|
-
|
86
|
-
Args:
|
87
|
-
messages (list[dict[str, str]]): The messages to complete.
|
88
|
-
model_name (LLMModelName): The model name.
|
89
|
-
temperature (float, optional): The temperature value. Defaults to 0.
|
90
|
-
timeout (int, optional): The timeout value in milliseconds. Defaults to 240000.
|
91
|
-
|
92
|
-
Returns:
|
93
|
-
str: The completed message content.
|
94
|
-
"""
|
95
|
-
return self._trigger_complete(messages, model_name, temperature, timeout)
|
96
|
-
|
97
|
-
@to_async
|
98
|
-
def async_complete(
|
99
|
-
self,
|
100
|
-
*,
|
101
|
-
messages: list,
|
102
|
-
model_name: LLMModelName,
|
103
|
-
temperature: float = 0,
|
104
|
-
timeout: int = 240000,
|
105
|
-
) -> str:
|
106
|
-
"""
|
107
|
-
Calls the completion endpoint asynchronously without streaming the response.
|
108
|
-
|
109
|
-
Args:
|
110
|
-
messages (list[dict[str, str]]): The messages to complete.
|
111
|
-
model_name (LLMModelName): The model name.
|
112
|
-
temperature (float, optional): The temperature value. Defaults to 0.
|
113
|
-
timeout (int, optional): The timeout value in milliseconds. Defaults to 240000.
|
114
|
-
|
115
|
-
Returns:
|
116
|
-
str: The completed message content.
|
117
|
-
"""
|
118
|
-
return self._trigger_complete(
|
119
|
-
messages,
|
120
|
-
model_name.name,
|
121
|
-
temperature,
|
122
|
-
timeout,
|
123
|
-
)
|
124
|
-
|
125
|
-
def _trigger_stream_complete(
|
126
|
-
self,
|
127
|
-
messages: list,
|
128
|
-
search_contexts: list,
|
129
|
-
model_name: str,
|
130
|
-
debug_info: dict,
|
131
|
-
timeout: int,
|
132
|
-
temperature: float,
|
133
|
-
):
|
134
|
-
return unique_sdk.Integrated.chat_stream_completion(
|
135
|
-
user_id=self.state.user_id,
|
136
|
-
company_id=self.state.company_id,
|
137
|
-
assistantMessageId=self.state.assistant_message_id,
|
138
|
-
userMessageId=self.state.user_message_id,
|
139
|
-
messages=messages,
|
140
|
-
chatId=self.state.chat_id,
|
141
|
-
searchContext=search_contexts,
|
142
|
-
debugInfo=debug_info,
|
143
|
-
model=model_name, # type: ignore
|
144
|
-
timeout=timeout,
|
145
|
-
temperature=temperature,
|
146
|
-
assistantId=self.state.assistant_id,
|
147
|
-
)
|
148
|
-
|
149
|
-
def _trigger_complete(
|
150
|
-
self,
|
151
|
-
messages: list,
|
152
|
-
model_name: str,
|
153
|
-
temperature: float,
|
154
|
-
timeout: int,
|
155
|
-
) -> str:
|
156
|
-
result = unique_sdk.ChatCompletion.create(
|
157
|
-
company_id=self.state.company_id,
|
158
|
-
model=model_name, # type: ignore
|
159
|
-
messages=messages,
|
160
|
-
timeout=timeout,
|
161
|
-
temperature=temperature,
|
162
|
-
)
|
163
|
-
return result.choices[-1]["message"]["content"]
|
@@ -1 +0,0 @@
|
|
1
|
-
from .async_wrapper import to_async # noqa: F401
|
@@ -1,13 +0,0 @@
|
|
1
|
-
import asyncio
|
2
|
-
from functools import wraps
|
3
|
-
from typing import Any, Callable, Coroutine, TypeVar
|
4
|
-
|
5
|
-
T = TypeVar("T")
|
6
|
-
|
7
|
-
|
8
|
-
def to_async(func: Callable[..., T]) -> Callable[..., Coroutine[Any, Any, T]]:
|
9
|
-
@wraps(func)
|
10
|
-
async def wrapper(*args, **kwargs) -> T:
|
11
|
-
return await asyncio.to_thread(func, *args, **kwargs)
|
12
|
-
|
13
|
-
return wrapper
|
unique_toolkit/sdk/init.py
DELETED
@@ -1,19 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
|
3
|
-
import unique_sdk
|
4
|
-
|
5
|
-
|
6
|
-
def init_sdk():
|
7
|
-
"""Initializes the SDK."""
|
8
|
-
unique_sdk.api_base = os.environ.get("API_BASE") # Required
|
9
|
-
|
10
|
-
# Optional if being run locally
|
11
|
-
unique_sdk.api_key = os.environ.get(
|
12
|
-
"API_KEY", "dummy"
|
13
|
-
) # Optional if being run locally
|
14
|
-
unique_sdk.app_id = os.environ.get(
|
15
|
-
"APP_ID", "dummy"
|
16
|
-
) # Optional if being run locally
|
17
|
-
endpoint_secret = os.environ.get("ENDPOINT_SECRET", None)
|
18
|
-
|
19
|
-
return endpoint_secret
|
unique_toolkit/search/service.py
DELETED
@@ -1,118 +0,0 @@
|
|
1
|
-
from typing import Literal
|
2
|
-
|
3
|
-
import unique_sdk
|
4
|
-
from unique_sdk import Content
|
5
|
-
|
6
|
-
from unique_toolkit.chat.state import ChatState
|
7
|
-
from unique_toolkit.performance.async_wrapper import to_async
|
8
|
-
|
9
|
-
|
10
|
-
class SearchService:
|
11
|
-
def __init__(self, state: ChatState):
|
12
|
-
self.state = state
|
13
|
-
|
14
|
-
def search(
|
15
|
-
self,
|
16
|
-
*,
|
17
|
-
search_string: str,
|
18
|
-
search_type: Literal["VECTOR", "COMBINED"],
|
19
|
-
limit: int,
|
20
|
-
scope_ids: list[str] = [],
|
21
|
-
):
|
22
|
-
"""
|
23
|
-
Performs a synchronous search in the knowledge base.
|
24
|
-
|
25
|
-
Args:
|
26
|
-
search_string (str): The search string.
|
27
|
-
search_type (Literal["VECTOR", "COMBINED"]): The type of search to perform.
|
28
|
-
limit (int): The maximum number of results to return.
|
29
|
-
|
30
|
-
Returns:
|
31
|
-
The search results.
|
32
|
-
"""
|
33
|
-
return self._trigger_search(search_string, search_type, limit, scope_ids)
|
34
|
-
|
35
|
-
@to_async
|
36
|
-
def async_search(
|
37
|
-
self,
|
38
|
-
*,
|
39
|
-
search_string: str,
|
40
|
-
search_type: Literal["VECTOR", "COMBINED"],
|
41
|
-
limit: int,
|
42
|
-
scope_ids: list[str] = [],
|
43
|
-
):
|
44
|
-
"""
|
45
|
-
Performs an asynchronous search in the knowledge base.
|
46
|
-
|
47
|
-
Args:
|
48
|
-
search_string (str): The search string.
|
49
|
-
search_type (Literal["VECTOR", "COMBINED"]): The type of search to perform.
|
50
|
-
limit (int): The maximum number of results to return.
|
51
|
-
|
52
|
-
Returns:
|
53
|
-
The search results.
|
54
|
-
"""
|
55
|
-
return self._trigger_search(search_string, search_type, limit, scope_ids)
|
56
|
-
|
57
|
-
def _trigger_search(
|
58
|
-
self,
|
59
|
-
search_string: str,
|
60
|
-
search_type: Literal["VECTOR", "COMBINED"],
|
61
|
-
limit: int,
|
62
|
-
scope_ids: list[str] = [],
|
63
|
-
):
|
64
|
-
scope_ids = scope_ids or self.state.scope_ids or []
|
65
|
-
return unique_sdk.Search.create(
|
66
|
-
user_id=self.state.user_id,
|
67
|
-
company_id=self.state.company_id,
|
68
|
-
chatId=self.state.chat_id,
|
69
|
-
searchString=search_string,
|
70
|
-
searchType=search_type,
|
71
|
-
scopeIds=scope_ids,
|
72
|
-
limit=limit,
|
73
|
-
chatOnly=self.state.chat_only,
|
74
|
-
)
|
75
|
-
|
76
|
-
def search_content(
|
77
|
-
self,
|
78
|
-
*,
|
79
|
-
where: dict,
|
80
|
-
) -> list[Content]:
|
81
|
-
"""
|
82
|
-
Performs a search in the knowledge base by filter.
|
83
|
-
|
84
|
-
Args:
|
85
|
-
where (dict): The search criteria.
|
86
|
-
|
87
|
-
Returns:
|
88
|
-
The search results.
|
89
|
-
"""
|
90
|
-
return self._trigger_search_content(where)
|
91
|
-
|
92
|
-
@to_async
|
93
|
-
def async_search_content(
|
94
|
-
self,
|
95
|
-
*,
|
96
|
-
where: dict,
|
97
|
-
) -> list[Content]:
|
98
|
-
"""
|
99
|
-
Performs an asynchronous search in the knowledge base by filter.
|
100
|
-
|
101
|
-
Args:
|
102
|
-
where (dict): The search criteria.
|
103
|
-
|
104
|
-
Returns:
|
105
|
-
The search results.
|
106
|
-
"""
|
107
|
-
return self._trigger_search_content(where)
|
108
|
-
|
109
|
-
def _trigger_search_content(
|
110
|
-
self,
|
111
|
-
where: dict,
|
112
|
-
) -> list[Content]:
|
113
|
-
return unique_sdk.Content.search(
|
114
|
-
user_id=self.state.user_id,
|
115
|
-
company_id=self.state.company_id,
|
116
|
-
chatId=self.state.chat_id,
|
117
|
-
where=where, # type: ignore
|
118
|
-
)
|
@@ -1,29 +0,0 @@
|
|
1
|
-
from http import HTTPStatus
|
2
|
-
|
3
|
-
import unique_sdk
|
4
|
-
|
5
|
-
from unique_toolkit.event.schema import Event
|
6
|
-
|
7
|
-
|
8
|
-
def verify_signature_and_construct_event(
|
9
|
-
headers, payload: bytes, endpoint_secret: str, logger
|
10
|
-
) -> Event:
|
11
|
-
sig_header = headers.get("X-Unique-Signature")
|
12
|
-
timestamp = headers.get("X-Unique-Created-At")
|
13
|
-
|
14
|
-
if not sig_header or not timestamp:
|
15
|
-
logger.error("⚠️ Webhook signature or timestamp headers missing.")
|
16
|
-
return False, HTTPStatus.BAD_REQUEST
|
17
|
-
|
18
|
-
try:
|
19
|
-
event = unique_sdk.Webhook.construct_event(
|
20
|
-
payload,
|
21
|
-
sig_header,
|
22
|
-
timestamp,
|
23
|
-
endpoint_secret,
|
24
|
-
)
|
25
|
-
logger.info("✅ Webhook signature verification successful.")
|
26
|
-
return Event(**event)
|
27
|
-
except unique_sdk.SignatureVerificationError as e:
|
28
|
-
logger.error("⚠️ Webhook signature verification failed. " + str(e))
|
29
|
-
return False, HTTPStatus.BAD_REQUEST
|
@@ -1,33 +0,0 @@
|
|
1
|
-
Metadata-Version: 2.1
|
2
|
-
Name: unique_toolkit
|
3
|
-
Version: 0.0.1
|
4
|
-
Summary:
|
5
|
-
License: MIT
|
6
|
-
Author: Unique Data Science
|
7
|
-
Author-email: datascience@unique.ch
|
8
|
-
Requires-Python: >=3.11,<4.0
|
9
|
-
Classifier: License :: OSI Approved :: MIT License
|
10
|
-
Classifier: Programming Language :: Python :: 3
|
11
|
-
Classifier: Programming Language :: Python :: 3.11
|
12
|
-
Classifier: Programming Language :: Python :: 3.12
|
13
|
-
Requires-Dist: pydantic (>=2.8.2,<3.0.0)
|
14
|
-
Requires-Dist: pyhumps (>=3.8.0,<4.0.0)
|
15
|
-
Requires-Dist: typing-extensions (>=4.9.0,<5.0.0)
|
16
|
-
Requires-Dist: unique-sdk (>=0.8.10,<0.9.0)
|
17
|
-
Description-Content-Type: text/markdown
|
18
|
-
|
19
|
-
# Unique Tool Kit
|
20
|
-
|
21
|
-
This package provides highlevel abstarctions and methods on top of `unique_sdk` to ease application development for the Unique Platform.
|
22
|
-
|
23
|
-
|
24
|
-
# Development instructions
|
25
|
-
|
26
|
-
1. Install poetry on your system (through `brew` or `pipx`).
|
27
|
-
|
28
|
-
2. Install `pyenv` and install python 3.11. `pyenv` is recommended as otherwise poetry uses the python version used to install itself and not the user preferred python version.
|
29
|
-
|
30
|
-
3. If you then run `python --version` in your terminal, you should be able to see python version as specified in `.python-version`.
|
31
|
-
|
32
|
-
4. Then finally run `poetry install` to install the package and all dependencies.
|
33
|
-
|
@@ -1,23 +0,0 @@
|
|
1
|
-
unique_toolkit/__init__.py,sha256=vObIHz3Vte5K6tlrytiNQQ1uqhibwnhSzB5WIt9cyIs,197
|
2
|
-
unique_toolkit/chat/__init__.py,sha256=TocIEJrMO5_xJB4ehFhslqoxOsV2oiLlglUdIWVLa-s,166
|
3
|
-
unique_toolkit/chat/messages.py,sha256=IuYPz8PoK6HyFsYigtfYkfz2wB8zhDJyjryWYC2D7k4,416
|
4
|
-
unique_toolkit/chat/service.py,sha256=UigC5-1wdQYoWLfzAU7h8hl_SB05YSCOTrxhU7dgMG4,5511
|
5
|
-
unique_toolkit/chat/state.py,sha256=7N9vsMl4mu1mbtFqg61T6-42UgnkXmLwhVfIwVnm6tc,1327
|
6
|
-
unique_toolkit/event/__init__.py,sha256=fqfQeanYjxLFGsrX97Ti3HpzLRCE3kDUlMBVXEvzr0s,80
|
7
|
-
unique_toolkit/event/constants.py,sha256=hwdCgSKBAZQYZSl1nFkP1yWiw6GBI7KbcNJrdxFxVm8,66
|
8
|
-
unique_toolkit/event/schema.py,sha256=sT0gtJN2LT0ormP7HfVot11Oub1YlzfBCKFj3G0Or4w,879
|
9
|
-
unique_toolkit/llm/__init__.py,sha256=3hT7PhdHnEQaqILJ6gGSe0cpkWEDMgZ_PHw1Q01W0e4,127
|
10
|
-
unique_toolkit/llm/json_parser.py,sha256=sHTe6_VuqqwrC1xCg9ud3VOukEzVSoj0Uce_sv7GEYE,528
|
11
|
-
unique_toolkit/llm/models.py,sha256=Gt691uSL74e3bdIm4UhAcp3Nw-jafnqJSgKdzhLJKww,1254
|
12
|
-
unique_toolkit/llm/service.py,sha256=UXXMo7MKcj7fbDKlv0gk2J00ClL1F7n0_6uiwOLSXoY,5226
|
13
|
-
unique_toolkit/observability/log_config.py,sha256=mfIu4cX95AiqOCdh2iW3iLoXtwrIrkPCXRtG_zYMhSs,679
|
14
|
-
unique_toolkit/performance/__init__.py,sha256=TYPrsYdxXhhom12ub0dzvR6dHtFdjnF-P506LYitj8Y,50
|
15
|
-
unique_toolkit/performance/async_executor.py,sha256=8N8GQn-MQN-8fX8DAbbYt7s2_91G0nchFQ25i9lIxsE,5555
|
16
|
-
unique_toolkit/performance/async_wrapper.py,sha256=MB3cgqcl-Y7Ltc9a_l8bkhfOGrds1lUtici17b9dGuQ,339
|
17
|
-
unique_toolkit/sdk/init.py,sha256=UQLbHxUjN_dttkiUznfJclYPHNVwANdf8w6H4SKs9Y4,482
|
18
|
-
unique_toolkit/search/service.py,sha256=hGzfFAdBt9Y5pwPHXTEmzid4FnEsXu9DiSzpw5gPv1Y,3167
|
19
|
-
unique_toolkit/security/verify.py,sha256=RxBw-gnWUsvqZT6rAt5Eq0vaR0rDY8AqUOTBZmQUItE,927
|
20
|
-
unique_toolkit-0.0.1.dist-info/LICENSE,sha256=nojs8Z8soUMb9wg1sAUZdJxyhzRGrUIXFeq0_I-zejo,1065
|
21
|
-
unique_toolkit-0.0.1.dist-info/METADATA,sha256=klnJs0EqSKVW0wz384xzI0PU-gaAbTIkb0EVHpLukhQ,1233
|
22
|
-
unique_toolkit-0.0.1.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
23
|
-
unique_toolkit-0.0.1.dist-info/RECORD,,
|
File without changes
|