unique_toolkit 0.8.0__tar.gz → 0.8.2__tar.gz
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-0.8.0 → unique_toolkit-0.8.2}/CHANGELOG.md +11 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/PKG-INFO +12 -1
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/pyproject.toml +1 -1
- unique_toolkit-0.8.2/unique_toolkit/app/dev_util.py +146 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/app/init_sdk.py +32 -1
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/app/schemas.py +9 -0
- unique_toolkit-0.8.2/unique_toolkit/app/unique_settings.py +134 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/chat/service.py +2 -9
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/content/service.py +49 -7
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/embedding/service.py +25 -3
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/framework_utilities/langchain/client.py +8 -8
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/framework_utilities/openai/client.py +4 -6
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/language_model/service.py +39 -14
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/short_term_memory/service.py +38 -6
- unique_toolkit-0.8.0/unique_toolkit/app/event_util.py +0 -24
- unique_toolkit-0.8.0/unique_toolkit/app/sse_client.py +0 -20
- unique_toolkit-0.8.0/unique_toolkit/app/unique_settings.py +0 -61
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/LICENSE +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/README.md +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/__init__.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/_common/_base_service.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/_common/_time_utils.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/_common/exception.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/_common/validate_required_values.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/_common/validators.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/app/__init__.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/app/init_logging.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/app/performance/async_tasks.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/app/performance/async_wrapper.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/app/verification.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/chat/__init__.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/chat/constants.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/chat/functions.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/chat/schemas.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/chat/state.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/chat/utils.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/content/__init__.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/content/constants.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/content/functions.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/content/schemas.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/content/utils.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/embedding/__init__.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/embedding/constants.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/embedding/functions.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/embedding/schemas.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/embedding/utils.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/__init__.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/config.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/constants.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/context_relevancy/constants.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/context_relevancy/prompts.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/context_relevancy/service.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/context_relevancy/utils.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/exception.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/hallucination/constants.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/hallucination/prompts.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/hallucination/service.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/hallucination/utils.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/output_parser.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/schemas.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/framework_utilities/langchain/history.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/framework_utilities/openai/message_builder.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/framework_utilities/utils.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/language_model/__init__.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/language_model/builder.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/language_model/constants.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/language_model/functions.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/language_model/infos.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/language_model/prompt.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/language_model/reference.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/language_model/schemas.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/language_model/utils.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/protocols/support.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/short_term_memory/__init__.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/short_term_memory/constants.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/short_term_memory/functions.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/short_term_memory/schemas.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/smart_rules/__init__.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/smart_rules/compile.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/tools/tool_definitions.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/tools/tool_definitionsV2.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/tools/tool_factory.py +0 -0
- {unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/tools/tool_progress_reporter.py +0 -0
|
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
|
|
9
|
+
## [0.8.2] - 2025-08-05
|
|
10
|
+
- Implement overloads for services for clearer dev experience
|
|
11
|
+
- Proper typing for SSE event handling
|
|
12
|
+
- Enhanced unique settings. Expose usage of default values in logs
|
|
13
|
+
- SDK Initialization from unique settings
|
|
14
|
+
- Add utilities for to run llm/agent flows for devs
|
|
15
|
+
|
|
16
|
+
## [0.8.1] - 2025-08-05
|
|
17
|
+
- Bump SDK version to support the latest features.
|
|
18
|
+
|
|
8
19
|
## [0.8.0] - 2025-08-04
|
|
9
20
|
- Add MCP support
|
|
10
21
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: unique_toolkit
|
|
3
|
-
Version: 0.8.
|
|
3
|
+
Version: 0.8.2
|
|
4
4
|
Summary:
|
|
5
5
|
License: Proprietary
|
|
6
6
|
Author: Martin Fadler
|
|
@@ -113,6 +113,17 @@ All notable changes to this project will be documented in this file.
|
|
|
113
113
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
|
114
114
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
115
115
|
|
|
116
|
+
|
|
117
|
+
## [0.8.2] - 2025-08-05
|
|
118
|
+
- Implement overloads for services for clearer dev experience
|
|
119
|
+
- Proper typing for SSE event handling
|
|
120
|
+
- Enhanced unique settings. Expose usage of default values in logs
|
|
121
|
+
- SDK Initialization from unique settings
|
|
122
|
+
- Add utilities for to run llm/agent flows for devs
|
|
123
|
+
|
|
124
|
+
## [0.8.1] - 2025-08-05
|
|
125
|
+
- Bump SDK version to support the latest features.
|
|
126
|
+
|
|
116
127
|
## [0.8.0] - 2025-08-04
|
|
117
128
|
- Add MCP support
|
|
118
129
|
|
|
@@ -0,0 +1,146 @@
|
|
|
1
|
+
import asyncio
|
|
2
|
+
import json
|
|
3
|
+
from logging import getLogger
|
|
4
|
+
from pathlib import Path
|
|
5
|
+
from typing import (
|
|
6
|
+
Awaitable,
|
|
7
|
+
Callable,
|
|
8
|
+
Generator,
|
|
9
|
+
TypeVar,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
from sseclient import SSEClient
|
|
13
|
+
|
|
14
|
+
from unique_toolkit.app import BaseEvent, ChatEvent, EventName
|
|
15
|
+
from unique_toolkit.app.init_sdk import init_unique_sdk
|
|
16
|
+
from unique_toolkit.app.unique_settings import UniqueSettings
|
|
17
|
+
|
|
18
|
+
T = TypeVar("T", bound=BaseEvent)
|
|
19
|
+
|
|
20
|
+
LOGGER = getLogger(__name__)
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def get_event_name_from_event_class(event_class: type[T]) -> EventName | None:
|
|
24
|
+
if event_class is ChatEvent:
|
|
25
|
+
return EventName.EXTERNAL_MODULE_CHOSEN
|
|
26
|
+
|
|
27
|
+
return None
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def get_sse_client(
|
|
31
|
+
unique_settings: UniqueSettings,
|
|
32
|
+
subscriptions: list[str],
|
|
33
|
+
) -> SSEClient:
|
|
34
|
+
headers = {
|
|
35
|
+
"Authorization": f"Bearer {unique_settings.app.key.get_secret_value()}",
|
|
36
|
+
"x-app-id": unique_settings.app.id.get_secret_value(),
|
|
37
|
+
"x-company-id": unique_settings.auth.company_id.get_secret_value(),
|
|
38
|
+
"x-user-id": unique_settings.auth.user_id.get_secret_value(),
|
|
39
|
+
"x-api-version": unique_settings.api.version,
|
|
40
|
+
}
|
|
41
|
+
return SSEClient(url=unique_settings.api.sse_url(subscriptions), headers=headers)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def get_event_generator(
|
|
45
|
+
unique_settings: UniqueSettings, event_type: type[T]
|
|
46
|
+
) -> Generator[T, None, None]:
|
|
47
|
+
"""
|
|
48
|
+
Generator that yields only events of the specified type from an SSE stream.
|
|
49
|
+
|
|
50
|
+
Args:
|
|
51
|
+
sse_client: The SSE client to read events from
|
|
52
|
+
event_type: The event class type to filter for
|
|
53
|
+
|
|
54
|
+
Yields:
|
|
55
|
+
Events matching the specified type
|
|
56
|
+
"""
|
|
57
|
+
event_name = get_event_name_from_event_class(event_type)
|
|
58
|
+
if (
|
|
59
|
+
event_name is None
|
|
60
|
+
or not issubclass(event_type, BaseEvent)
|
|
61
|
+
or event_type is BaseEvent
|
|
62
|
+
):
|
|
63
|
+
raise ValueError(f"Event model {event_type} is not a valid event model")
|
|
64
|
+
|
|
65
|
+
subscription = event_name.value
|
|
66
|
+
|
|
67
|
+
for sse_event in get_sse_client(unique_settings, [subscription]):
|
|
68
|
+
try:
|
|
69
|
+
payload = json.loads(sse_event.data)
|
|
70
|
+
parsed_event = event_type.model_validate(payload)
|
|
71
|
+
if parsed_event is None:
|
|
72
|
+
continue
|
|
73
|
+
|
|
74
|
+
yield parsed_event
|
|
75
|
+
|
|
76
|
+
except Exception as e:
|
|
77
|
+
LOGGER.error(f"Could not parse SSE event data as JSON: {e}")
|
|
78
|
+
continue
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
def run_demo_with_sse_client(
|
|
82
|
+
unique_settings: UniqueSettings,
|
|
83
|
+
handler: Callable[[BaseEvent], Awaitable[None] | None],
|
|
84
|
+
event_type: type[BaseEvent],
|
|
85
|
+
) -> None:
|
|
86
|
+
"""
|
|
87
|
+
Run a demo with an SSE client using sync handler.
|
|
88
|
+
|
|
89
|
+
Args:
|
|
90
|
+
unique_settings: The unique settings to use for the SSE client
|
|
91
|
+
handler: The sync handler to use for the SSE client
|
|
92
|
+
event_type: The type of event to use for the SSE client
|
|
93
|
+
"""
|
|
94
|
+
|
|
95
|
+
event_name = get_event_name_from_event_class(event_type)
|
|
96
|
+
if event_name is None:
|
|
97
|
+
return
|
|
98
|
+
|
|
99
|
+
init_unique_sdk(unique_settings=unique_settings)
|
|
100
|
+
is_async_handler = asyncio.iscoroutinefunction(handler)
|
|
101
|
+
|
|
102
|
+
for event in get_event_generator(unique_settings, event_type):
|
|
103
|
+
if is_async_handler:
|
|
104
|
+
loop = asyncio.get_event_loop()
|
|
105
|
+
loop.run_until_complete(handler(event))
|
|
106
|
+
else:
|
|
107
|
+
handler(event)
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
def load_event(file_path: Path, event_type: type[BaseEvent]) -> BaseEvent:
|
|
111
|
+
with file_path.open("r") as file:
|
|
112
|
+
event = json.load(file)
|
|
113
|
+
|
|
114
|
+
return event_type.model_validate(event)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
def run_demo_with_with_saved_event(
|
|
118
|
+
unique_settings: UniqueSettings,
|
|
119
|
+
handler: Callable[[BaseEvent], Awaitable[None] | None],
|
|
120
|
+
event_type: type[BaseEvent],
|
|
121
|
+
file_path: Path,
|
|
122
|
+
) -> None:
|
|
123
|
+
"""
|
|
124
|
+
Run a demo with an SSE client.
|
|
125
|
+
|
|
126
|
+
Note: event_type is the type of event that the handler expects.
|
|
127
|
+
|
|
128
|
+
Args:
|
|
129
|
+
unique_settings: The unique settings to use for the SSE client
|
|
130
|
+
handler: The handler to use for the SSE client
|
|
131
|
+
event_type: The type of event to use for the SSE client
|
|
132
|
+
"""
|
|
133
|
+
init_unique_sdk(unique_settings=unique_settings)
|
|
134
|
+
|
|
135
|
+
event_name = get_event_name_from_event_class(event_type)
|
|
136
|
+
if event_name is None:
|
|
137
|
+
return
|
|
138
|
+
|
|
139
|
+
event = load_event(file_path, event_type)
|
|
140
|
+
if event is None:
|
|
141
|
+
raise ValueError(f"Event not found in {file_path}")
|
|
142
|
+
|
|
143
|
+
if asyncio.iscoroutinefunction(handler):
|
|
144
|
+
asyncio.run(handler(event))
|
|
145
|
+
else:
|
|
146
|
+
handler(event)
|
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import os
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import overload
|
|
2
4
|
|
|
3
5
|
import unique_sdk
|
|
6
|
+
from typing_extensions import deprecated
|
|
7
|
+
|
|
8
|
+
from unique_toolkit.app.unique_settings import UniqueSettings
|
|
4
9
|
|
|
5
10
|
|
|
6
11
|
def get_env(var_name, default=None, strict=False):
|
|
@@ -24,12 +29,38 @@ def get_env(var_name, default=None, strict=False):
|
|
|
24
29
|
return val or default
|
|
25
30
|
|
|
26
31
|
|
|
27
|
-
|
|
32
|
+
@overload
|
|
33
|
+
def init_unique_sdk(*, env_file: Path | None = None): ...
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@overload
|
|
37
|
+
def init_unique_sdk(*, unique_settings: UniqueSettings): ...
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
def init_unique_sdk(
|
|
41
|
+
*, unique_settings: UniqueSettings | None = None, env_file: Path | None = None
|
|
42
|
+
):
|
|
43
|
+
if unique_settings:
|
|
44
|
+
unique_sdk.api_key = unique_settings.app.key.get_secret_value()
|
|
45
|
+
unique_sdk.app_id = unique_settings.app.id.get_secret_value()
|
|
46
|
+
unique_sdk.api_base = unique_settings.api.sdk_url()
|
|
47
|
+
elif env_file:
|
|
48
|
+
unique_settings = UniqueSettings.from_env(env_file=env_file)
|
|
49
|
+
unique_sdk.api_key = unique_settings.app.key.get_secret_value()
|
|
50
|
+
unique_sdk.app_id = unique_settings.app.id.get_secret_value()
|
|
51
|
+
unique_sdk.api_base = unique_settings.api.sdk_url()
|
|
52
|
+
|
|
53
|
+
|
|
54
|
+
@deprecated("Use init_unique_sdk instead")
|
|
55
|
+
def init_sdk(
|
|
56
|
+
strict_all_vars: bool = False,
|
|
57
|
+
):
|
|
28
58
|
"""Initialize the SDK.
|
|
29
59
|
|
|
30
60
|
Args:
|
|
31
61
|
strict_all_vars (bool, optional): This method raises a ValueError if strict and no value is found in the environment. Defaults to False.
|
|
32
62
|
"""
|
|
63
|
+
|
|
33
64
|
unique_sdk.api_key = get_env("API_KEY", default="dummy", strict=strict_all_vars)
|
|
34
65
|
unique_sdk.app_id = get_env("APP_ID", default="dummy", strict=strict_all_vars)
|
|
35
66
|
unique_sdk.api_base = get_env("API_BASE", default=None, strict=strict_all_vars)
|
|
@@ -19,6 +19,15 @@ model_config = ConfigDict(
|
|
|
19
19
|
|
|
20
20
|
class EventName(StrEnum):
|
|
21
21
|
EXTERNAL_MODULE_CHOSEN = "unique.chat.external-module.chosen"
|
|
22
|
+
USER_MESSAGE_CREATED = "unique.chat.user-message.created"
|
|
23
|
+
INGESTION_CONTENT_UPLOADED = "unique.ingestion.content.uploaded"
|
|
24
|
+
INGESTION_CONTENT_FINISHED = "unique.ingestion.content.finished"
|
|
25
|
+
MAGIC_TABLE_IMPORT_COLUMNS = "unique.magic-table.import-columns"
|
|
26
|
+
MAGIC_TABLE_ADD_META_DATA = "unique.magic-table.add-meta-data"
|
|
27
|
+
MAGIC_TABLE_ADD_DOCUMENT = "unique.magic-table.add-document"
|
|
28
|
+
MAGIC_TABLE_DELETE_ROW = "unique.magic-table.delete-row"
|
|
29
|
+
MAGIC_TABLE_DELETE_COLUMN = "unique.magic-table.delete-column"
|
|
30
|
+
MAGIC_TABLE_UPDATE_CELL = "unique.magic-table.update-cell"
|
|
22
31
|
|
|
23
32
|
|
|
24
33
|
class BaseEvent(BaseModel):
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
from logging import getLogger
|
|
2
|
+
from pathlib import Path
|
|
3
|
+
from typing import Self, TypeVar
|
|
4
|
+
from urllib.parse import urlparse, urlunparse
|
|
5
|
+
|
|
6
|
+
from pydantic import Field, SecretStr, model_validator
|
|
7
|
+
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
8
|
+
|
|
9
|
+
logger = getLogger(__name__)
|
|
10
|
+
|
|
11
|
+
T = TypeVar("T", bound=BaseSettings)
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def warn_about_defaults(instance: T) -> T:
|
|
15
|
+
"""Log warnings for fields that are using default values."""
|
|
16
|
+
for field_name, model_field in instance.model_fields.items():
|
|
17
|
+
field_value = getattr(instance, field_name)
|
|
18
|
+
if field_value == model_field.default:
|
|
19
|
+
logger.warning(
|
|
20
|
+
f"Using default value for '{field_name}': {model_field.default}"
|
|
21
|
+
)
|
|
22
|
+
return instance
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class UniqueApp(BaseSettings):
|
|
26
|
+
id: SecretStr = Field(default=SecretStr("dummy_id"))
|
|
27
|
+
key: SecretStr = Field(default=SecretStr("dummy_key"))
|
|
28
|
+
base_url: str = Field(
|
|
29
|
+
default="http://localhost:8092/",
|
|
30
|
+
deprecated="Use UniqueApi.base_url instead",
|
|
31
|
+
)
|
|
32
|
+
endpoint: str = Field(default="dummy")
|
|
33
|
+
endpoint_secret: SecretStr = Field(default=SecretStr("dummy_secret"))
|
|
34
|
+
|
|
35
|
+
@model_validator(mode="after")
|
|
36
|
+
def _warn_about_defaults(self) -> Self:
|
|
37
|
+
return warn_about_defaults(self)
|
|
38
|
+
|
|
39
|
+
model_config = SettingsConfigDict(
|
|
40
|
+
env_prefix="unique_app_",
|
|
41
|
+
env_file_encoding="utf-8",
|
|
42
|
+
case_sensitive=False,
|
|
43
|
+
extra="ignore",
|
|
44
|
+
)
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
class UniqueApi(BaseSettings):
|
|
48
|
+
base_url: str = Field(
|
|
49
|
+
default="http://localhost:8092/",
|
|
50
|
+
description="The base URL of the Unique API. Ask your admin to provide you with the correct URL.",
|
|
51
|
+
)
|
|
52
|
+
version: str = Field(default="2023-12-06")
|
|
53
|
+
|
|
54
|
+
model_config = SettingsConfigDict(
|
|
55
|
+
env_prefix="unique_api_",
|
|
56
|
+
env_file_encoding="utf-8",
|
|
57
|
+
case_sensitive=False,
|
|
58
|
+
extra="ignore",
|
|
59
|
+
)
|
|
60
|
+
|
|
61
|
+
@model_validator(mode="after")
|
|
62
|
+
def _warn_about_defaults(self) -> Self:
|
|
63
|
+
return warn_about_defaults(self)
|
|
64
|
+
|
|
65
|
+
def sse_url(self, subscriptions: list[str]) -> str:
|
|
66
|
+
parsed = urlparse(self.base_url)
|
|
67
|
+
return urlunparse(
|
|
68
|
+
parsed._replace(
|
|
69
|
+
path="/public/event-socket/events/stream",
|
|
70
|
+
query=f"subscriptions={','.join(subscriptions)}",
|
|
71
|
+
fragment=None,
|
|
72
|
+
)
|
|
73
|
+
)
|
|
74
|
+
|
|
75
|
+
def sdk_url(self) -> str:
|
|
76
|
+
parsed = urlparse(self.base_url)
|
|
77
|
+
|
|
78
|
+
path = "/public/chat"
|
|
79
|
+
if parsed.hostname and "qa.unique" in parsed.hostname:
|
|
80
|
+
path = "/public/chat-gen2"
|
|
81
|
+
return urlunparse(parsed._replace(path=path, query=None, fragment=None))
|
|
82
|
+
|
|
83
|
+
def openai_proxy_url(self) -> str:
|
|
84
|
+
parsed = urlparse(self.base_url)
|
|
85
|
+
return urlunparse(
|
|
86
|
+
parsed._replace(path="/public/openai-proxy/", query=None, fragment=None)
|
|
87
|
+
)
|
|
88
|
+
|
|
89
|
+
|
|
90
|
+
class UniqueAuth(BaseSettings):
|
|
91
|
+
company_id: SecretStr = Field(default=SecretStr("dummy_company_id"))
|
|
92
|
+
user_id: SecretStr = Field(default=SecretStr("dummy_user_id"))
|
|
93
|
+
|
|
94
|
+
model_config = SettingsConfigDict(
|
|
95
|
+
env_prefix="unique_auth_",
|
|
96
|
+
env_file_encoding="utf-8",
|
|
97
|
+
case_sensitive=False,
|
|
98
|
+
extra="ignore",
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
@model_validator(mode="after")
|
|
102
|
+
def _warn_about_defaults(self) -> Self:
|
|
103
|
+
return warn_about_defaults(self)
|
|
104
|
+
|
|
105
|
+
|
|
106
|
+
class UniqueSettings:
|
|
107
|
+
def __init__(self, auth: UniqueAuth, app: UniqueApp, api: UniqueApi):
|
|
108
|
+
self.app = app
|
|
109
|
+
self.auth = auth
|
|
110
|
+
self.api = api
|
|
111
|
+
|
|
112
|
+
@classmethod
|
|
113
|
+
def from_env(cls, env_file: Path | None = None) -> "UniqueSettings":
|
|
114
|
+
"""Initialize settings from environment variables and/or env file.
|
|
115
|
+
|
|
116
|
+
Args:
|
|
117
|
+
env_file: Optional path to environment file. If provided, will load variables from this file.
|
|
118
|
+
|
|
119
|
+
Returns:
|
|
120
|
+
UniqueSettings instance with values loaded from environment/env file.
|
|
121
|
+
|
|
122
|
+
Raises:
|
|
123
|
+
FileNotFoundError: If env_file is provided but does not exist.
|
|
124
|
+
ValidationError: If required environment variables are missing.
|
|
125
|
+
"""
|
|
126
|
+
if env_file and not env_file.exists():
|
|
127
|
+
raise FileNotFoundError(f"Environment file not found: {env_file}")
|
|
128
|
+
|
|
129
|
+
# Initialize settings with environment file if provided
|
|
130
|
+
env_file_str = str(env_file) if env_file else None
|
|
131
|
+
auth = UniqueAuth(_env_file=env_file_str)
|
|
132
|
+
app = UniqueApp(_env_file=env_file_str)
|
|
133
|
+
api = UniqueApi(_env_file=env_file_str)
|
|
134
|
+
return cls(auth=auth, app=app, api=api)
|
|
@@ -57,15 +57,6 @@ logger = logging.getLogger(f"toolkit.{DOMAIN_NAME}.{__name__}")
|
|
|
57
57
|
class ChatService:
|
|
58
58
|
"""
|
|
59
59
|
Provides all functionalities to manage the chat session.
|
|
60
|
-
|
|
61
|
-
Attributes:
|
|
62
|
-
company_id (str | None): The company ID.
|
|
63
|
-
user_id (str | None): The user ID.
|
|
64
|
-
assistant_message_id (str | None): The assistant message ID.
|
|
65
|
-
user_message_id (str | None): The user message ID.
|
|
66
|
-
chat_id (str | None): The chat ID.
|
|
67
|
-
assistant_id (str | None): The assistant ID.
|
|
68
|
-
user_message_text (str | None): The user message text.
|
|
69
60
|
"""
|
|
70
61
|
|
|
71
62
|
def __init__(self, event: ChatEvent | Event):
|
|
@@ -88,6 +79,7 @@ class ChatService:
|
|
|
88
79
|
|
|
89
80
|
Returns:
|
|
90
81
|
Event | BaseEvent | None: The event object.
|
|
82
|
+
|
|
91
83
|
"""
|
|
92
84
|
return self._event
|
|
93
85
|
|
|
@@ -101,6 +93,7 @@ class ChatService:
|
|
|
101
93
|
|
|
102
94
|
Returns:
|
|
103
95
|
str | None: The company identifier.
|
|
96
|
+
|
|
104
97
|
"""
|
|
105
98
|
return self._company_id
|
|
106
99
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import logging
|
|
2
2
|
from pathlib import Path
|
|
3
|
-
from typing import Any
|
|
3
|
+
from typing import Any, overload
|
|
4
4
|
|
|
5
5
|
import unique_sdk
|
|
6
6
|
from requests import Response
|
|
@@ -35,13 +35,30 @@ logger = logging.getLogger(f"toolkit.{DOMAIN_NAME}.{__name__}")
|
|
|
35
35
|
class ContentService:
|
|
36
36
|
"""
|
|
37
37
|
Provides methods for searching, downloading and uploading content in the knowledge base.
|
|
38
|
+
"""
|
|
39
|
+
|
|
40
|
+
@deprecated(
|
|
41
|
+
"Use __init__ with company_id, user_id and chat_id instead or use the classmethod `from_event`"
|
|
42
|
+
)
|
|
43
|
+
@overload
|
|
44
|
+
def __init__(self, event: Event | ChatEvent | BaseEvent): ...
|
|
45
|
+
|
|
46
|
+
"""
|
|
47
|
+
Initialize the ContentService with an event (deprecated)
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
@overload
|
|
51
|
+
def __init__(
|
|
52
|
+
self,
|
|
53
|
+
*,
|
|
54
|
+
company_id: str,
|
|
55
|
+
user_id: str,
|
|
56
|
+
chat_id: str | None,
|
|
57
|
+
metadata_filter: dict | None = None,
|
|
58
|
+
): ...
|
|
38
59
|
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
company_id (str): The company ID.
|
|
42
|
-
user_id (str): The user ID.
|
|
43
|
-
chat_id (str): The chat ID. Defaults to None
|
|
44
|
-
metadata_filter (dict | None): is only initialised from an Event(Deprecated) or ChatEvent.
|
|
60
|
+
"""
|
|
61
|
+
Initialize the ContentService with a company_id, user_id and chat_id and metadata_filter.
|
|
45
62
|
"""
|
|
46
63
|
|
|
47
64
|
def __init__(
|
|
@@ -50,7 +67,12 @@ class ContentService:
|
|
|
50
67
|
company_id: str | None = None,
|
|
51
68
|
user_id: str | None = None,
|
|
52
69
|
chat_id: str | None = None,
|
|
70
|
+
metadata_filter: dict | None = None,
|
|
53
71
|
):
|
|
72
|
+
"""
|
|
73
|
+
Initialize the ContentService with a company_id, user_id and chat_id.
|
|
74
|
+
"""
|
|
75
|
+
|
|
54
76
|
self._event = event # Changed to protected attribute
|
|
55
77
|
self._metadata_filter = None
|
|
56
78
|
if event:
|
|
@@ -64,6 +86,26 @@ class ContentService:
|
|
|
64
86
|
self._company_id: str = company_id
|
|
65
87
|
self._user_id: str = user_id
|
|
66
88
|
self._chat_id: str | None = chat_id
|
|
89
|
+
self._metadata_filter = metadata_filter
|
|
90
|
+
|
|
91
|
+
@classmethod
|
|
92
|
+
def from_event(cls, event: Event | ChatEvent | BaseEvent):
|
|
93
|
+
"""
|
|
94
|
+
Initialize the ContentService with an event.
|
|
95
|
+
"""
|
|
96
|
+
chat_id = None
|
|
97
|
+
metadata_filter = None
|
|
98
|
+
|
|
99
|
+
if isinstance(event, (ChatEvent | Event)):
|
|
100
|
+
chat_id = event.payload.chat_id
|
|
101
|
+
metadata_filter = event.payload.metadata_filter
|
|
102
|
+
|
|
103
|
+
return cls(
|
|
104
|
+
company_id=event.company_id,
|
|
105
|
+
user_id=event.user_id,
|
|
106
|
+
chat_id=chat_id,
|
|
107
|
+
metadata_filter=metadata_filter,
|
|
108
|
+
)
|
|
67
109
|
|
|
68
110
|
@property
|
|
69
111
|
@deprecated(
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import overload
|
|
2
|
+
|
|
1
3
|
from typing_extensions import deprecated
|
|
2
4
|
|
|
3
5
|
from unique_toolkit._common._base_service import BaseService
|
|
@@ -11,10 +13,23 @@ from unique_toolkit.embedding.schemas import Embeddings
|
|
|
11
13
|
class EmbeddingService(BaseService):
|
|
12
14
|
"""
|
|
13
15
|
Provides methods to interact with the Embedding service.
|
|
16
|
+
"""
|
|
14
17
|
|
|
15
|
-
|
|
16
|
-
company_id
|
|
17
|
-
|
|
18
|
+
@deprecated(
|
|
19
|
+
"Use __init__ with company_id and user_id instead or use the classmethod `from_event`"
|
|
20
|
+
)
|
|
21
|
+
@overload
|
|
22
|
+
def __init__(self, event: Event | BaseEvent): ...
|
|
23
|
+
|
|
24
|
+
"""
|
|
25
|
+
Initialize the EmbeddingService with an event (deprecated)
|
|
26
|
+
"""
|
|
27
|
+
|
|
28
|
+
@overload
|
|
29
|
+
def __init__(self, *, company_id: str, user_id: str): ...
|
|
30
|
+
|
|
31
|
+
"""
|
|
32
|
+
Initialize the EmbeddingService with a company_id and user_id.
|
|
18
33
|
"""
|
|
19
34
|
|
|
20
35
|
def __init__(
|
|
@@ -32,6 +47,13 @@ class EmbeddingService(BaseService):
|
|
|
32
47
|
self._company_id: str = company_id
|
|
33
48
|
self._user_id: str = user_id
|
|
34
49
|
|
|
50
|
+
@classmethod
|
|
51
|
+
def from_event(cls, event: Event | BaseEvent):
|
|
52
|
+
"""
|
|
53
|
+
Initialize the EmbeddingService with an event.
|
|
54
|
+
"""
|
|
55
|
+
return cls(company_id=event.company_id, user_id=event.user_id)
|
|
56
|
+
|
|
35
57
|
@property
|
|
36
58
|
@deprecated(
|
|
37
59
|
"The event property is deprecated and will be removed in a future version."
|
{unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/framework_utilities/langchain/client.py
RENAMED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import importlib.util
|
|
2
2
|
import logging
|
|
3
|
-
from pathlib import Path
|
|
4
3
|
|
|
5
4
|
from unique_toolkit.app.unique_settings import UniqueSettings
|
|
6
5
|
from unique_toolkit.framework_utilities.utils import get_default_headers
|
|
@@ -23,11 +22,13 @@ else:
|
|
|
23
22
|
raise LangchainNotInstalledError()
|
|
24
23
|
|
|
25
24
|
|
|
26
|
-
def get_client(
|
|
25
|
+
def get_client(
|
|
26
|
+
unique_settings: UniqueSettings, model: str = "AZURE_GPT_4o_2024_0806"
|
|
27
|
+
) -> ChatOpenAI:
|
|
27
28
|
"""Get a Langchain ChatOpenAI client instance.
|
|
28
29
|
|
|
29
30
|
Args:
|
|
30
|
-
|
|
31
|
+
unique_settings: UniqueSettings instance
|
|
31
32
|
|
|
32
33
|
Returns:
|
|
33
34
|
ChatOpenAI client instance
|
|
@@ -35,11 +36,10 @@ def get_client(env_file: Path | None = None) -> ChatOpenAI:
|
|
|
35
36
|
Raises:
|
|
36
37
|
LangchainNotInstalledError: If langchain-openai package is not installed
|
|
37
38
|
"""
|
|
38
|
-
settings = UniqueSettings.from_env(env_file=env_file)
|
|
39
39
|
|
|
40
40
|
return ChatOpenAI(
|
|
41
|
-
base_url=
|
|
42
|
-
default_headers=get_default_headers(
|
|
43
|
-
model=
|
|
44
|
-
api_key=
|
|
41
|
+
base_url=unique_settings.api.openai_proxy_url(),
|
|
42
|
+
default_headers=get_default_headers(unique_settings.app, unique_settings.auth),
|
|
43
|
+
model=model,
|
|
44
|
+
api_key=unique_settings.app.key,
|
|
45
45
|
)
|
{unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/framework_utilities/openai/client.py
RENAMED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import importlib.util
|
|
2
2
|
import logging
|
|
3
|
-
from pathlib import Path
|
|
4
3
|
|
|
5
4
|
from unique_toolkit.app.unique_settings import UniqueSettings
|
|
6
5
|
from unique_toolkit.framework_utilities.utils import get_default_headers
|
|
@@ -23,7 +22,7 @@ else:
|
|
|
23
22
|
raise OpenAINotInstalledError()
|
|
24
23
|
|
|
25
24
|
|
|
26
|
-
def get_openai_client(
|
|
25
|
+
def get_openai_client(unique_settings: UniqueSettings) -> OpenAI:
|
|
27
26
|
"""Get an OpenAI client instance.
|
|
28
27
|
|
|
29
28
|
Args:
|
|
@@ -35,11 +34,10 @@ def get_openai_client(env_file: Path | None = None) -> OpenAI:
|
|
|
35
34
|
Raises:
|
|
36
35
|
OpenAINotInstalledError: If OpenAI package is not installed
|
|
37
36
|
"""
|
|
38
|
-
|
|
39
|
-
default_headers = get_default_headers(settings.app, settings.auth)
|
|
37
|
+
default_headers = get_default_headers(unique_settings.app, unique_settings.auth)
|
|
40
38
|
|
|
41
39
|
return OpenAI(
|
|
42
|
-
api_key=
|
|
43
|
-
base_url=
|
|
40
|
+
api_key=unique_settings.app.key.get_secret_value(),
|
|
41
|
+
base_url=unique_settings.api.openai_proxy_url(),
|
|
44
42
|
default_headers=default_headers,
|
|
45
43
|
)
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import logging
|
|
2
|
-
from typing import Any, Optional, Type
|
|
2
|
+
from typing import Any, Optional, Type, overload
|
|
3
3
|
|
|
4
4
|
from pydantic import BaseModel
|
|
5
5
|
from typing_extensions import deprecated
|
|
@@ -33,36 +33,61 @@ logger = logging.getLogger(f"toolkit.{DOMAIN_NAME}.{__name__}")
|
|
|
33
33
|
class LanguageModelService:
|
|
34
34
|
"""
|
|
35
35
|
Provides methods to interact with the Language Model by generating responses.
|
|
36
|
+
"""
|
|
37
|
+
|
|
38
|
+
@deprecated(
|
|
39
|
+
"Use __init__ with company_id and user_id instead or use the classmethod `from_event`"
|
|
40
|
+
)
|
|
41
|
+
@overload
|
|
42
|
+
def __init__(self, event: Event | ChatEvent | BaseEvent): ...
|
|
43
|
+
|
|
44
|
+
"""
|
|
45
|
+
Initialize the LanguageModelService with an event (deprecated)
|
|
46
|
+
"""
|
|
47
|
+
|
|
48
|
+
@overload
|
|
49
|
+
def __init__(self, *, company_id: str, user_id: str): ...
|
|
36
50
|
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
user_id (str | None, optional): The user identifier. Defaults to None.
|
|
40
|
-
chat_id (str | None, optional): The chat identifier. Defaults to None.
|
|
41
|
-
assistant_id (str | None, optional): The assistant identifier. Defaults to None.
|
|
51
|
+
"""
|
|
52
|
+
Initialize the LanguageModelService with a company_id and user_id.
|
|
42
53
|
"""
|
|
43
54
|
|
|
44
55
|
def __init__(
|
|
45
56
|
self,
|
|
46
|
-
event: Event | BaseEvent | None = None,
|
|
57
|
+
event: Event | ChatEvent | BaseEvent | None = None,
|
|
47
58
|
company_id: str | None = None,
|
|
48
59
|
user_id: str | None = None,
|
|
49
|
-
|
|
50
|
-
assistant_id: str | None = None,
|
|
60
|
+
**kwargs: dict[str, Any], # only here for backward compatibility
|
|
51
61
|
):
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
if event:
|
|
62
|
+
if isinstance(event, (ChatEvent, Event)):
|
|
63
|
+
self._event = event
|
|
64
|
+
self._chat_id: str | None = event.payload.chat_id
|
|
65
|
+
self._assistant_id: str | None = event.payload.assistant_id
|
|
57
66
|
self._company_id = event.company_id
|
|
58
67
|
self._user_id = event.user_id
|
|
59
68
|
if isinstance(event, (ChatEvent, Event)):
|
|
60
69
|
self._chat_id = event.payload.chat_id
|
|
61
70
|
self._assistant_id = event.payload.assistant_id
|
|
71
|
+
elif isinstance(event, BaseEvent):
|
|
72
|
+
self._event = event
|
|
73
|
+
self._company_id = event.company_id
|
|
74
|
+
self._user_id = event.user_id
|
|
75
|
+
self._chat_id: str | None = None
|
|
76
|
+
self._assistant_id: str | None = None
|
|
62
77
|
else:
|
|
63
78
|
[company_id, user_id] = validate_required_values([company_id, user_id])
|
|
79
|
+
self._event = None
|
|
64
80
|
self._company_id: str = company_id
|
|
65
81
|
self._user_id: str = user_id
|
|
82
|
+
self._chat_id: str | None = None
|
|
83
|
+
self._assistant_id: str | None = None
|
|
84
|
+
|
|
85
|
+
@classmethod
|
|
86
|
+
def from_event(cls, event: BaseEvent):
|
|
87
|
+
"""
|
|
88
|
+
Initialize the LanguageModelService with an event.
|
|
89
|
+
"""
|
|
90
|
+
return cls(company_id=event.company_id, user_id=event.user_id)
|
|
66
91
|
|
|
67
92
|
@property
|
|
68
93
|
@deprecated(
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import overload
|
|
2
|
+
|
|
1
3
|
from typing_extensions import deprecated
|
|
2
4
|
|
|
3
5
|
from unique_toolkit._common.validate_required_values import validate_required_values
|
|
@@ -16,17 +18,35 @@ from .schemas import ShortTermMemory
|
|
|
16
18
|
class ShortTermMemoryService:
|
|
17
19
|
"""
|
|
18
20
|
Provides methods to manage short term memory.
|
|
21
|
+
"""
|
|
22
|
+
|
|
23
|
+
@deprecated(
|
|
24
|
+
"Use __init__ with company_id and user_id instead or use the classmethod `from_event`"
|
|
25
|
+
)
|
|
26
|
+
@overload
|
|
27
|
+
def __init__(self, event: Event | ChatEvent | BaseEvent): ...
|
|
28
|
+
|
|
29
|
+
"""
|
|
30
|
+
Initialize the ShortTermMemoryService with an event (deprecated)
|
|
31
|
+
"""
|
|
32
|
+
|
|
33
|
+
@overload
|
|
34
|
+
def __init__(
|
|
35
|
+
self,
|
|
36
|
+
*,
|
|
37
|
+
company_id: str,
|
|
38
|
+
user_id: str,
|
|
39
|
+
chat_id: str | None,
|
|
40
|
+
message_id: str | None,
|
|
41
|
+
): ...
|
|
19
42
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
company_id (str | None): The company ID.
|
|
23
|
-
chat_id (str | None): The chat ID.
|
|
24
|
-
message_id (str | None): The message ID.
|
|
43
|
+
"""
|
|
44
|
+
Initialize the ShortTermMemoryService with a company_id, user_id, chat_id and message_id.
|
|
25
45
|
"""
|
|
26
46
|
|
|
27
47
|
def __init__(
|
|
28
48
|
self,
|
|
29
|
-
event: Event | BaseEvent | None = None,
|
|
49
|
+
event: Event | ChatEvent | BaseEvent | None = None,
|
|
30
50
|
user_id: str | None = None,
|
|
31
51
|
company_id: str | None = None,
|
|
32
52
|
chat_id: str | None = None,
|
|
@@ -50,6 +70,18 @@ class ShortTermMemoryService:
|
|
|
50
70
|
self._chat_id: str | None = chat_id
|
|
51
71
|
self._message_id: str | None = message_id
|
|
52
72
|
|
|
73
|
+
@classmethod
|
|
74
|
+
def from_event(cls, event: ChatEvent):
|
|
75
|
+
"""
|
|
76
|
+
Initialize the ShortTermMemoryService with a chat event.
|
|
77
|
+
"""
|
|
78
|
+
return cls(
|
|
79
|
+
company_id=event.company_id,
|
|
80
|
+
user_id=event.user_id,
|
|
81
|
+
chat_id=event.payload.chat_id,
|
|
82
|
+
message_id=event.payload.user_message.id,
|
|
83
|
+
)
|
|
84
|
+
|
|
53
85
|
@property
|
|
54
86
|
@deprecated(
|
|
55
87
|
"The event property is deprecated and will be removed in a future version."
|
|
@@ -1,24 +0,0 @@
|
|
|
1
|
-
import json
|
|
2
|
-
from logging import getLogger
|
|
3
|
-
from typing import Literal, overload
|
|
4
|
-
|
|
5
|
-
from unique_toolkit.app import ChatEvent, EventName
|
|
6
|
-
|
|
7
|
-
LOGGER = getLogger(__name__)
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
@overload
|
|
11
|
-
def load_and_filter_event(
|
|
12
|
-
event: dict,
|
|
13
|
-
event_type: Literal[EventName.EXTERNAL_MODULE_CHOSEN],
|
|
14
|
-
) -> type[ChatEvent] | None: ...
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
def load_and_filter_event(event: dict, event_type: EventName):
|
|
18
|
-
event = json.loads(event.data)
|
|
19
|
-
|
|
20
|
-
match event_type:
|
|
21
|
-
case EventName.EXTERNAL_MODULE_CHOSEN:
|
|
22
|
-
return ChatEvent(**event)
|
|
23
|
-
|
|
24
|
-
return None
|
|
@@ -1,20 +0,0 @@
|
|
|
1
|
-
from logging import getLogger
|
|
2
|
-
|
|
3
|
-
from sseclient import SSEClient
|
|
4
|
-
|
|
5
|
-
from unique_toolkit.app.unique_settings import UniqueSettings
|
|
6
|
-
|
|
7
|
-
LOGGER = getLogger(__name__)
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
def get_sse_client(
|
|
11
|
-
unique_settings: UniqueSettings,
|
|
12
|
-
subscriptions: list[str],
|
|
13
|
-
) -> SSEClient:
|
|
14
|
-
url = f"{unique_settings.app.base_url}/public/event-socket/events/stream?subscriptions={','.join(subscriptions)}"
|
|
15
|
-
headers = {
|
|
16
|
-
"Authorization": f"Bearer {unique_settings.app.key.get_secret_value()}",
|
|
17
|
-
"x-app-id": unique_settings.app.id.get_secret_value(),
|
|
18
|
-
"x-company-id": unique_settings.auth.company_id.get_secret_value(),
|
|
19
|
-
}
|
|
20
|
-
return SSEClient(url=url, headers=headers)
|
|
@@ -1,61 +0,0 @@
|
|
|
1
|
-
from pathlib import Path
|
|
2
|
-
|
|
3
|
-
from pydantic import SecretStr
|
|
4
|
-
from pydantic_settings import BaseSettings, SettingsConfigDict
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
class UniqueApp(BaseSettings):
|
|
8
|
-
id: SecretStr
|
|
9
|
-
key: SecretStr
|
|
10
|
-
base_url: str
|
|
11
|
-
endpoint: str
|
|
12
|
-
endpoint_secret: SecretStr
|
|
13
|
-
|
|
14
|
-
model_config = SettingsConfigDict(
|
|
15
|
-
env_prefix="unique_app_",
|
|
16
|
-
env_file_encoding="utf-8",
|
|
17
|
-
case_sensitive=False,
|
|
18
|
-
extra="ignore",
|
|
19
|
-
)
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
class UniqueAuth(BaseSettings):
|
|
23
|
-
company_id: SecretStr
|
|
24
|
-
user_id: SecretStr
|
|
25
|
-
|
|
26
|
-
model_config = SettingsConfigDict(
|
|
27
|
-
env_prefix="unique_auth_",
|
|
28
|
-
env_file_encoding="utf-8",
|
|
29
|
-
case_sensitive=False,
|
|
30
|
-
extra="ignore",
|
|
31
|
-
)
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
class UniqueSettings:
|
|
35
|
-
def __init__(self, auth: UniqueAuth, app: UniqueApp):
|
|
36
|
-
self.app = app
|
|
37
|
-
self.auth = auth
|
|
38
|
-
|
|
39
|
-
@classmethod
|
|
40
|
-
def from_env(cls, env_file: Path | None = None) -> "UniqueSettings":
|
|
41
|
-
"""Initialize settings from environment variables and/or env file.
|
|
42
|
-
|
|
43
|
-
Args:
|
|
44
|
-
env_file: Optional path to environment file. If provided, will load variables from this file.
|
|
45
|
-
|
|
46
|
-
Returns:
|
|
47
|
-
UniqueSettings instance with values loaded from environment/env file.
|
|
48
|
-
|
|
49
|
-
Raises:
|
|
50
|
-
FileNotFoundError: If env_file is provided but does not exist.
|
|
51
|
-
ValidationError: If required environment variables are missing.
|
|
52
|
-
"""
|
|
53
|
-
if env_file and not env_file.exists():
|
|
54
|
-
raise FileNotFoundError(f"Environment file not found: {env_file}")
|
|
55
|
-
|
|
56
|
-
# Initialize settings with environment file if provided
|
|
57
|
-
env_file_str = str(env_file) if env_file else None
|
|
58
|
-
auth = UniqueAuth(_env_file=env_file_str, _env_file_encoding="utf-8")
|
|
59
|
-
app = UniqueApp(_env_file=env_file_str, _env_file_encoding="utf-8")
|
|
60
|
-
|
|
61
|
-
return cls(auth=auth, app=app)
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/_common/validate_required_values.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/app/performance/async_wrapper.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/context_relevancy/prompts.py
RENAMED
|
File without changes
|
{unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/context_relevancy/service.py
RENAMED
|
File without changes
|
{unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/context_relevancy/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
{unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/hallucination/constants.py
RENAMED
|
File without changes
|
{unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/hallucination/prompts.py
RENAMED
|
File without changes
|
{unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/hallucination/service.py
RENAMED
|
File without changes
|
{unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/evaluators/hallucination/utils.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unique_toolkit-0.8.0 → unique_toolkit-0.8.2}/unique_toolkit/tools/tool_progress_reporter.py
RENAMED
|
File without changes
|