unique_toolkit 0.7.35__py3-none-any.whl → 0.7.37__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.
@@ -0,0 +1,24 @@
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
@@ -0,0 +1,20 @@
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}",
17
+ "x-app-id": unique_settings.app.id,
18
+ "x-company-id": unique_settings.auth.company_id,
19
+ }
20
+ return SSEClient(url=url, headers=headers)
@@ -0,0 +1,61 @@
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)
@@ -0,0 +1,19 @@
1
+ from langchain_core.messages import AIMessage, BaseMessage, HumanMessage
2
+
3
+ from unique_toolkit.chat import ChatMessage as UniqueMessage
4
+ from unique_toolkit.chat import ChatMessageRole as UniqueRole
5
+
6
+
7
+ def unique_history_to_langchain_history(
8
+ unique_history: list[UniqueMessage],
9
+ ) -> list[BaseMessage]:
10
+ history = []
11
+ for m in unique_history:
12
+ if m.role == UniqueRole.ASSISTANT:
13
+ history.append(AIMessage(content=m.content))
14
+ elif m.role == UniqueRole.USER:
15
+ history.append(HumanMessage(content=m.content))
16
+ else:
17
+ raise Exception("Unknown message role.")
18
+
19
+ return history
@@ -114,6 +114,7 @@ def _preprocess_message(text: str) -> str:
114
114
  def replace_source_colon(match):
115
115
  numbers = re.findall(r"\d+", match.group(0))
116
116
  return "".join(f"[{n}]" for n in numbers)
117
+
117
118
  text = re.sub(r"\[source:\s*([\d,\s]+)\]", replace_source_colon, text)
118
119
 
119
120
  # Replace '[[A], [B], ...]', '[[A], B, C, ...]', and '[X, Y, Z]' with [A][B][C]... where A,B,C are numbers
@@ -122,7 +123,9 @@ def _preprocess_message(text: str) -> str:
122
123
  return "".join(f"[{n}]" for n in numbers)
123
124
 
124
125
  text = re.sub(
125
- r"(?:\[\[(\d+)\](?:,\s*(?:\[)?\d+(?:\])?)*\]|\[([\d,\s]+)\])", replace_combined_brackets, text
126
+ r"(?:\[\[(\d+)\](?:,\s*(?:\[)?\d+(?:\])?)*\]|\[([\d,\s]+)\])",
127
+ replace_combined_brackets,
128
+ text,
126
129
  )
127
130
 
128
131
  return text
@@ -41,9 +41,9 @@ class ShortTermMemoryService:
41
41
  self._message_id = event.payload.user_message.id
42
42
  else:
43
43
  [company_id, user_id] = validate_required_values([company_id, user_id])
44
- assert (
45
- chat_id or message_id
46
- ), "Either chat_id or message_id must be provided"
44
+
45
+ if not (chat_id or message_id):
46
+ raise ValueError("Chat_id or message_id must be provided")
47
47
 
48
48
  self._company_id: str = company_id
49
49
  self._user_id: str = user_id
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unique_toolkit
3
- Version: 0.7.35
3
+ Version: 0.7.37
4
4
  Summary:
5
5
  License: Proprietary
6
6
  Author: Martin Fadler
@@ -12,9 +12,11 @@ Classifier: Programming Language :: Python :: 3.11
12
12
  Classifier: Programming Language :: Python :: 3.12
13
13
  Requires-Dist: numpy (>=1.26.4,<2.0.0)
14
14
  Requires-Dist: pydantic (>=2.8.2,<3.0.0)
15
+ Requires-Dist: pydantic-settings (>=2.10.1,<3.0.0)
15
16
  Requires-Dist: pyhumps (>=3.8.0,<4.0.0)
16
17
  Requires-Dist: python-dotenv (>=1.0.1,<2.0.0)
17
18
  Requires-Dist: regex (>=2024.5.15,<2025.0.0)
19
+ Requires-Dist: sseclient (>=0.0.27,<0.0.28)
18
20
  Requires-Dist: tiktoken (>=0.7.0,<0.8.0)
19
21
  Requires-Dist: typing-extensions (>=4.9.0,<5.0.0)
20
22
  Requires-Dist: unique-sdk (>=0.9.40,<0.10.0)
@@ -111,6 +113,10 @@ All notable changes to this project will be documented in this file.
111
113
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
112
114
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
113
115
 
116
+ ## [0.7.36] - 2025-07-25
117
+ - Fix issues with settings
118
+ - Add testing to unique settings
119
+
114
120
  ## [0.7.35] - 2025-07-23
115
121
  - Bump version of SDK to have access to the latest features and fixes
116
122
 
@@ -5,11 +5,14 @@ unique_toolkit/_common/exception.py,sha256=caQIE1btsQnpKCHqL2cgWUSbHup06enQu_Pt7
5
5
  unique_toolkit/_common/validate_required_values.py,sha256=Y_M1ub9gIKP9qZ45F6Zq3ZHtuIqhmOjl8Z2Vd3avg8w,588
6
6
  unique_toolkit/_common/validators.py,sha256=l7-hWyRTZ3aF_e73oTQFZdz93s06VhNWVpkERbg2a64,1569
7
7
  unique_toolkit/app/__init__.py,sha256=jgwWfu27U911kZE1yRq920ZULGLAQGycD3222YxUvsY,1182
8
+ unique_toolkit/app/event_util.py,sha256=lfI64OcOXJZhh2GcVTmvE8AVc888jPWhi7l1vEzDsgs,535
8
9
  unique_toolkit/app/init_logging.py,sha256=Sh26SRxOj8i8dzobKhYha2lLrkrMTHfB1V4jR3h23gQ,678
9
10
  unique_toolkit/app/init_sdk.py,sha256=Nv4Now4pMfM0AgRhbtatLpm_39rKxn0WmRLwmPhRl-8,1285
10
11
  unique_toolkit/app/performance/async_tasks.py,sha256=H0l3OAcosLwNHZ8d2pd-Di4wHIXfclEvagi5kfqLFPA,1941
11
12
  unique_toolkit/app/performance/async_wrapper.py,sha256=yVVcRDkcdyfjsxro-N29SBvi-7773wnfDplef6-y8xw,1077
12
13
  unique_toolkit/app/schemas.py,sha256=f1WHnEqSMX2C_c9vtOOVNSdlSH--jK22GDbtRAKPVjc,5044
14
+ unique_toolkit/app/sse_client.py,sha256=UrX41CIbw0DDBn8mOx_3rT1X8GCjqqYQcxhasoT0C-Q,611
15
+ unique_toolkit/app/unique_settings.py,sha256=fi3V9Dru1G1YK7Pxju_KBGiNJHkHdx7JzpDglcvMZro,1820
13
16
  unique_toolkit/app/verification.py,sha256=GxFFwcJMy25fCA_Xe89wKW7bgqOu8PAs5y8QpHF0GSc,3861
14
17
  unique_toolkit/chat/__init__.py,sha256=LRs2G-JTVuci4lbtHTkVUiNcZcSR6uqqfnAyo7af6nY,619
15
18
  unique_toolkit/chat/constants.py,sha256=05kq6zjqUVB2d6_P7s-90nbljpB3ryxwCI-CAz0r2O4,83
@@ -44,13 +47,14 @@ unique_toolkit/evaluators/hallucination/service.py,sha256=k8qro5Lw4Ak58m4HYp3G4H
44
47
  unique_toolkit/evaluators/hallucination/utils.py,sha256=gO2AOzDQwVTev2_5vDKgJ9A6A9e0himJyAta_wglVG8,8326
45
48
  unique_toolkit/evaluators/output_parser.py,sha256=eI72qkzK1dZyUvnfP2SOAQCGBj_-PwX5wy_aLPMsJMY,883
46
49
  unique_toolkit/evaluators/schemas.py,sha256=Jaue6Uhx75X1CyHKWj8sT3RE1JZXTqoLtfLt2xQNCX8,2507
50
+ unique_toolkit/framework_utilities/langchain/history.py,sha256=8ejA0utPUIlX4z8gtX9IkVFiooY-vOT1UcjI_MoJaAU,638
47
51
  unique_toolkit/language_model/__init__.py,sha256=lRQyLlbwHbNFf4-0foBU13UGb09lwEeodbVsfsSgaCk,1971
48
52
  unique_toolkit/language_model/builder.py,sha256=69WCcmkm2rMP2-YEH_EjHiEp6OzwjwCs8VbhjVJaCe0,3168
49
53
  unique_toolkit/language_model/constants.py,sha256=B-topqW0r83dkC_25DeQfnPk3n53qzIHUCBS7YJ0-1U,119
50
54
  unique_toolkit/language_model/functions.py,sha256=WhgHbJgz4Z2aZt9TLdOpI0PGyYWA5R90tdwkwdDeT8c,11987
51
55
  unique_toolkit/language_model/infos.py,sha256=w5__BVG-IiiEYKG1FwM838wzqNbYI3eCCEDocKezc0I,34801
52
56
  unique_toolkit/language_model/prompt.py,sha256=JSawaLjQg3VR-E2fK8engFyJnNdk21zaO8pPIodzN4Q,3991
53
- unique_toolkit/language_model/reference.py,sha256=jd-JPuqLwEJDs56im56o-AdiT73pdwNtSzcW38LZ53o,8565
57
+ unique_toolkit/language_model/reference.py,sha256=nkX2VFz-IrUz8yqyc3G5jUMNwrNpxITBrMEKkbqqYoI,8583
54
58
  unique_toolkit/language_model/schemas.py,sha256=AeuDRJFblGzEYcEMyrlxpOPk12Di3J45I9rT2xZrhEU,14332
55
59
  unique_toolkit/language_model/service.py,sha256=VRkUk2XbijqGlnTTvqU7uCue6qtT7lpLd_Y8f3bWv1I,10486
56
60
  unique_toolkit/language_model/utils.py,sha256=bPQ4l6_YO71w-zaIPanUUmtbXC1_hCvLK0tAFc3VCRc,1902
@@ -59,10 +63,10 @@ unique_toolkit/short_term_memory/__init__.py,sha256=2mI3AUrffgH7Yt-xS57EGqnHf7jn
59
63
  unique_toolkit/short_term_memory/constants.py,sha256=698CL6-wjup2MvU19RxSmQk3gX7aqW_OOpZB7sbz_Xg,34
60
64
  unique_toolkit/short_term_memory/functions.py,sha256=3WiK-xatY5nh4Dr5zlDUye1k3E6kr41RiscwtTplw5k,4484
61
65
  unique_toolkit/short_term_memory/schemas.py,sha256=OhfcXyF6ACdwIXW45sKzjtZX_gkcJs8FEZXcgQTNenw,1406
62
- unique_toolkit/short_term_memory/service.py,sha256=cqpXA0nMbi4PhFweg-Cql3u0RvaTi5c8Xjv0uHMiSGc,8112
66
+ unique_toolkit/short_term_memory/service.py,sha256=8sW7cFJRd4vcRfotJSWb0uHZYl-e5hQWp3G1SddL5Bg,8110
63
67
  unique_toolkit/smart_rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
64
68
  unique_toolkit/smart_rules/compile.py,sha256=cxWjb2dxEI2HGsakKdVCkSNi7VK9mr08w5sDcFCQyWI,9553
65
- unique_toolkit-0.7.35.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
66
- unique_toolkit-0.7.35.dist-info/METADATA,sha256=iwPmfbrhO_p3uKGwvUWGinbQVjqmq24_EJBPjSstFnQ,25014
67
- unique_toolkit-0.7.35.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
68
- unique_toolkit-0.7.35.dist-info/RECORD,,
69
+ unique_toolkit-0.7.37.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
70
+ unique_toolkit-0.7.37.dist-info/METADATA,sha256=Do_KkEttqekSmZCpzHCZGApVgYB-6ho6XegupsPtn6s,25195
71
+ unique_toolkit-0.7.37.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
72
+ unique_toolkit-0.7.37.dist-info/RECORD,,