unique_toolkit 0.6.6__tar.gz → 0.6.8__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.6.6 → unique_toolkit-0.6.8}/CHANGELOG.md +6 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/PKG-INFO +7 -1
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/pyproject.toml +1 -1
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/app/schemas.py +1 -1
- unique_toolkit-0.6.8/unique_toolkit/app/verification.py +112 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/language_model/builder.py +12 -3
- unique_toolkit-0.6.6/unique_toolkit/app/verification.py +0 -59
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/LICENSE +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/README.md +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/__init__.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/_common/_base_service.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/_common/_time_utils.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/_common/exception.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/_common/validate_required_values.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/_common/validators.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/app/__init__.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/app/init_logging.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/app/init_sdk.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/app/performance/async_tasks.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/app/performance/async_wrapper.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/chat/__init__.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/chat/constants.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/chat/functions.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/chat/schemas.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/chat/service.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/chat/state.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/chat/utils.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/content/__init__.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/content/constants.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/content/functions.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/content/schemas.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/content/service.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/content/utils.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/embedding/__init__.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/embedding/constants.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/embedding/functions.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/embedding/schemas.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/embedding/service.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/embedding/utils.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/__init__.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/config.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/constants.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/context_relevancy/constants.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/context_relevancy/prompts.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/context_relevancy/service.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/context_relevancy/utils.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/exception.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/hallucination/constants.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/hallucination/prompts.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/hallucination/service.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/hallucination/utils.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/output_parser.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/schemas.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/language_model/__init__.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/language_model/constants.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/language_model/functions.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/language_model/infos.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/language_model/prompt.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/language_model/schemas.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/language_model/service.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/language_model/utils.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/short_term_memory/__init__.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/short_term_memory/constants.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/short_term_memory/functions.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/short_term_memory/schemas.py +0 -0
- {unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/short_term_memory/service.py +0 -0
@@ -5,6 +5,12 @@ 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
|
+
## [0.6.8] - 2025-03-11
|
9
|
+
- Add `verify_request_and_construct_event` to `verification.py`
|
10
|
+
|
11
|
+
## [0.6.7] - 2025-03-10
|
12
|
+
- Extend language model message builder
|
13
|
+
|
8
14
|
## [0.6.6] - 2025-03-10
|
9
15
|
- Add o1, o1-mini and o3-mini models
|
10
16
|
- Remove deprecated gpt4 models
|
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.1
|
2
2
|
Name: unique_toolkit
|
3
|
-
Version: 0.6.
|
3
|
+
Version: 0.6.8
|
4
4
|
Summary:
|
5
5
|
License: Proprietary
|
6
6
|
Author: Martin Fadler
|
@@ -111,6 +111,12 @@ All notable changes to this project will be documented in this file.
|
|
111
111
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
|
112
112
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
113
113
|
|
114
|
+
## [0.6.8] - 2025-03-11
|
115
|
+
- Add `verify_request_and_construct_event` to `verification.py`
|
116
|
+
|
117
|
+
## [0.6.7] - 2025-03-10
|
118
|
+
- Extend language model message builder
|
119
|
+
|
114
120
|
## [0.6.6] - 2025-03-10
|
115
121
|
- Add o1, o1-mini and o3-mini models
|
116
122
|
- Remove deprecated gpt4 models
|
@@ -102,7 +102,7 @@ class ChatEventPayload(BaseModel):
|
|
102
102
|
metadata_filter: Optional[dict[str, Any]] = None
|
103
103
|
|
104
104
|
|
105
|
-
@deprecated("""
|
105
|
+
@deprecated("""Use `ChatEventPayload` instead.
|
106
106
|
This class will be removed in the next major version.""")
|
107
107
|
class EventPayload(ChatEventPayload):
|
108
108
|
user_message: EventUserMessage
|
@@ -0,0 +1,112 @@
|
|
1
|
+
import json
|
2
|
+
import logging
|
3
|
+
import os
|
4
|
+
from typing import Callable, TypeVar
|
5
|
+
|
6
|
+
import unique_sdk
|
7
|
+
from pydantic import ValidationError
|
8
|
+
|
9
|
+
from unique_toolkit.app.schemas import Event
|
10
|
+
|
11
|
+
logger = logging.getLogger(f"toolkit.{__name__}")
|
12
|
+
|
13
|
+
|
14
|
+
class WebhookVerificationError(Exception):
|
15
|
+
"""Custom exception for webhook verification errors."""
|
16
|
+
|
17
|
+
pass
|
18
|
+
|
19
|
+
|
20
|
+
T = TypeVar("T")
|
21
|
+
|
22
|
+
|
23
|
+
def verify_signature_and_construct_event(
|
24
|
+
headers: dict[str, str],
|
25
|
+
payload: bytes,
|
26
|
+
endpoint_secret: str,
|
27
|
+
logger: logging.Logger = logger,
|
28
|
+
event_constructor: Callable[..., T] = Event,
|
29
|
+
) -> T:
|
30
|
+
"""
|
31
|
+
Verify the signature of a webhook and construct an event object.
|
32
|
+
|
33
|
+
Args:
|
34
|
+
headers (Dict[str, str]): The headers of the webhook request.
|
35
|
+
payload (bytes): The raw payload of the webhook request.
|
36
|
+
endpoint_secret (str): The secret used to verify the webhook signature.
|
37
|
+
logger (logging.Logger): A logger instance for logging messages.
|
38
|
+
event_constructor (Callable[..., T]): A callable that constructs an event object.
|
39
|
+
Returns:
|
40
|
+
T: The constructed event object.
|
41
|
+
|
42
|
+
Raises:
|
43
|
+
WebhookVerificationError: If there's an error during verification or event construction.
|
44
|
+
"""
|
45
|
+
|
46
|
+
sig_header = headers.get("X-Unique-Signature")
|
47
|
+
timestamp = headers.get("X-Unique-Created-At")
|
48
|
+
|
49
|
+
if not sig_header or not timestamp:
|
50
|
+
logger.error("⚠️ Webhook signature or timestamp headers missing.")
|
51
|
+
raise WebhookVerificationError("Signature or timestamp headers missing")
|
52
|
+
|
53
|
+
try:
|
54
|
+
event = unique_sdk.Webhook.construct_event(
|
55
|
+
payload,
|
56
|
+
sig_header,
|
57
|
+
timestamp,
|
58
|
+
endpoint_secret,
|
59
|
+
)
|
60
|
+
logger.info("✅ Webhook signature verification successful.")
|
61
|
+
return event_constructor(**event)
|
62
|
+
except unique_sdk.SignatureVerificationError as e:
|
63
|
+
logger.error("⚠️ Webhook signature verification failed. " + str(e))
|
64
|
+
raise WebhookVerificationError(f"Signature verification failed: {str(e)}")
|
65
|
+
|
66
|
+
|
67
|
+
def verify_request_and_construct_event(
|
68
|
+
assistant_name: str,
|
69
|
+
payload: bytes,
|
70
|
+
headers: dict[str, str],
|
71
|
+
event_constructor: Callable[..., Event] = Event,
|
72
|
+
) -> tuple[str, int] | tuple[Event, int]:
|
73
|
+
"""Check the payload, authenticate and genenrate the event if the payload is correct"""
|
74
|
+
logger.info(f"{assistant_name} - received request")
|
75
|
+
|
76
|
+
try:
|
77
|
+
payload_decoded = json.loads(payload)
|
78
|
+
except json.decoder.JSONDecodeError as e:
|
79
|
+
logger.error(f"Error decoding payload: {e}", exc_info=True)
|
80
|
+
return "Invalid payload", 400
|
81
|
+
|
82
|
+
endpoint_secret = os.environ.get("ENDPOINT_SECRET", None)
|
83
|
+
if endpoint_secret:
|
84
|
+
response = verify_signature_and_construct_event(
|
85
|
+
headers=headers, # type: ignore
|
86
|
+
payload=payload,
|
87
|
+
endpoint_secret=endpoint_secret,
|
88
|
+
logger=logger,
|
89
|
+
event_constructor=event_constructor,
|
90
|
+
)
|
91
|
+
if isinstance(response, tuple):
|
92
|
+
return response # Error response
|
93
|
+
event = response # This is an event since it is not a tuple
|
94
|
+
else:
|
95
|
+
try:
|
96
|
+
event = event_constructor(**payload_decoded)
|
97
|
+
except ValidationError as e:
|
98
|
+
# pydantic errors https://docs.pydantic.dev/2.10/errors/errors/
|
99
|
+
logger.error(f"Validation error with model: {e.json()}", exc_info=True)
|
100
|
+
raise ValidationError(e)
|
101
|
+
except ValueError as e:
|
102
|
+
logger.error(f"Error deserializing event: {e}", exc_info=True)
|
103
|
+
return "Invalid event", 400
|
104
|
+
|
105
|
+
if not event.payload.name == assistant_name:
|
106
|
+
logger.error(
|
107
|
+
f"{assistant_name}: Incorrect assistant: {event.payload.name}: Expected {assistant_name}"
|
108
|
+
)
|
109
|
+
return f"Not {assistant_name} event", 400
|
110
|
+
|
111
|
+
logger.info(f"{assistant_name} - received event")
|
112
|
+
return event, 200
|
@@ -3,6 +3,7 @@ from typing_extensions import Self
|
|
3
3
|
from unique_toolkit.language_model import (
|
4
4
|
LanguageModelAssistantMessage,
|
5
5
|
LanguageModelMessage,
|
6
|
+
LanguageModelMessageRole,
|
6
7
|
LanguageModelMessages,
|
7
8
|
LanguageModelSystemMessage,
|
8
9
|
LanguageModelToolMessage,
|
@@ -14,6 +15,11 @@ class MessagesBuilder:
|
|
14
15
|
def __init__(self):
|
15
16
|
self.messages: list[LanguageModelMessage] = []
|
16
17
|
|
18
|
+
def message_append(self, role: LanguageModelMessageRole, content: str):
|
19
|
+
message = LanguageModelMessage(role=role, content=content)
|
20
|
+
self.messages.append(message)
|
21
|
+
return self
|
22
|
+
|
17
23
|
def system_message_append(self, content: str) -> Self:
|
18
24
|
"""Appends a system message to the messages list."""
|
19
25
|
message = LanguageModelSystemMessage(content=content)
|
@@ -26,15 +32,18 @@ class MessagesBuilder:
|
|
26
32
|
self.messages.append(message)
|
27
33
|
return self # Return self to allow method chaining
|
28
34
|
|
29
|
-
def image_message_append(
|
30
|
-
|
35
|
+
def image_message_append(
|
36
|
+
self, content: str, images: list[str], role=LanguageModelMessageRole.USER
|
37
|
+
) -> Self:
|
38
|
+
message = LanguageModelMessage(
|
39
|
+
role=role,
|
31
40
|
content=[
|
32
41
|
{"type": "text", "text": content},
|
33
42
|
*[
|
34
43
|
{"type": "image_url", "imageUrl": {"url": image}}
|
35
44
|
for image in images
|
36
45
|
],
|
37
|
-
]
|
46
|
+
],
|
38
47
|
)
|
39
48
|
self.messages.append(message)
|
40
49
|
return self
|
@@ -1,59 +0,0 @@
|
|
1
|
-
import logging
|
2
|
-
from typing import Callable, TypeVar
|
3
|
-
|
4
|
-
import unique_sdk
|
5
|
-
|
6
|
-
from unique_toolkit.app.schemas import Event
|
7
|
-
|
8
|
-
|
9
|
-
class WebhookVerificationError(Exception):
|
10
|
-
"""Custom exception for webhook verification errors."""
|
11
|
-
|
12
|
-
pass
|
13
|
-
|
14
|
-
|
15
|
-
T = TypeVar("T")
|
16
|
-
|
17
|
-
|
18
|
-
def verify_signature_and_construct_event(
|
19
|
-
headers: dict[str, str],
|
20
|
-
payload: bytes,
|
21
|
-
endpoint_secret: str,
|
22
|
-
logger: logging.Logger = logging.getLogger(__name__),
|
23
|
-
event_constructor: Callable[..., T] = Event,
|
24
|
-
) -> T:
|
25
|
-
"""
|
26
|
-
Verify the signature of a webhook and construct an event object.
|
27
|
-
|
28
|
-
Args:
|
29
|
-
headers (Dict[str, str]): The headers of the webhook request.
|
30
|
-
payload (bytes): The raw payload of the webhook request.
|
31
|
-
endpoint_secret (str): The secret used to verify the webhook signature.
|
32
|
-
logger (logging.Logger): A logger instance for logging messages.
|
33
|
-
event_constructor (Callable[..., T]): A callable that constructs an event object.
|
34
|
-
Returns:
|
35
|
-
T: The constructed event object.
|
36
|
-
|
37
|
-
Raises:
|
38
|
-
WebhookVerificationError: If there's an error during verification or event construction.
|
39
|
-
"""
|
40
|
-
|
41
|
-
sig_header = headers.get("X-Unique-Signature")
|
42
|
-
timestamp = headers.get("X-Unique-Created-At")
|
43
|
-
|
44
|
-
if not sig_header or not timestamp:
|
45
|
-
logger.error("⚠️ Webhook signature or timestamp headers missing.")
|
46
|
-
raise WebhookVerificationError("Signature or timestamp headers missing")
|
47
|
-
|
48
|
-
try:
|
49
|
-
event = unique_sdk.Webhook.construct_event(
|
50
|
-
payload,
|
51
|
-
sig_header,
|
52
|
-
timestamp,
|
53
|
-
endpoint_secret,
|
54
|
-
)
|
55
|
-
logger.info("✅ Webhook signature verification successful.")
|
56
|
-
return event_constructor(**event)
|
57
|
-
except unique_sdk.SignatureVerificationError as e:
|
58
|
-
logger.error("⚠️ Webhook signature verification failed. " + str(e))
|
59
|
-
raise WebhookVerificationError(f"Signature verification failed: {str(e)}")
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/_common/validate_required_values.py
RENAMED
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|
{unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/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
|
File without changes
|
File without changes
|
{unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/context_relevancy/prompts.py
RENAMED
File without changes
|
{unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/context_relevancy/service.py
RENAMED
File without changes
|
{unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/context_relevancy/utils.py
RENAMED
File without changes
|
File without changes
|
{unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/hallucination/constants.py
RENAMED
File without changes
|
{unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/hallucination/prompts.py
RENAMED
File without changes
|
{unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/unique_toolkit/evaluators/hallucination/service.py
RENAMED
File without changes
|
{unique_toolkit-0.6.6 → unique_toolkit-0.6.8}/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
|