unique_toolkit 0.7.38__py3-none-any.whl → 0.7.40__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,45 @@
1
+ import importlib.util
2
+ import logging
3
+ from pathlib import Path
4
+
5
+ from unique_toolkit.app.unique_settings import UniqueSettings
6
+ from unique_toolkit.framework_utilities.utils import get_default_headers
7
+
8
+ logger = logging.getLogger("toolkit.framework_utilities.langchain")
9
+
10
+
11
+ class LangchainNotInstalledError(ImportError):
12
+ """Raised when langchain-openai package is not installed but functionality requiring it is accessed."""
13
+
14
+ def __init__(self):
15
+ super().__init__(
16
+ "langchain-openai package is not installed. Install it with 'poetry install --with langchain'."
17
+ )
18
+
19
+
20
+ if importlib.util.find_spec("langchain_openai") is not None:
21
+ from langchain_openai import ChatOpenAI
22
+ else:
23
+ raise LangchainNotInstalledError()
24
+
25
+
26
+ def get_client(env_file: Path | None = None) -> ChatOpenAI:
27
+ """Get a Langchain ChatOpenAI client instance.
28
+
29
+ Args:
30
+ env_file: Optional path to environment file
31
+
32
+ Returns:
33
+ ChatOpenAI client instance
34
+
35
+ Raises:
36
+ LangchainNotInstalledError: If langchain-openai package is not installed
37
+ """
38
+ settings = UniqueSettings.from_env(env_file=env_file)
39
+
40
+ return ChatOpenAI(
41
+ base_url=settings.app.base_url + "/openai-proxy/",
42
+ default_headers=get_default_headers(settings.app, settings.auth),
43
+ model="AZURE_GPT_4o_2024_0806",
44
+ api_key=settings.app.key,
45
+ )
@@ -0,0 +1,45 @@
1
+ import importlib.util
2
+ import logging
3
+ from pathlib import Path
4
+
5
+ from unique_toolkit.app.unique_settings import UniqueSettings
6
+ from unique_toolkit.framework_utilities.utils import get_default_headers
7
+
8
+ logger = logging.getLogger("toolkit.framework_utilities.openai")
9
+
10
+
11
+ class OpenAINotInstalledError(ImportError):
12
+ """Raised when OpenAI package is not installed but functionality requiring it is accessed."""
13
+
14
+ def __init__(self):
15
+ super().__init__(
16
+ "OpenAI package is not installed. Install it with 'poetry install --with openai'."
17
+ )
18
+
19
+
20
+ if importlib.util.find_spec("openai") is not None:
21
+ from openai import OpenAI
22
+ else:
23
+ raise OpenAINotInstalledError()
24
+
25
+
26
+ def get_openai_client(env_file: Path | None = None) -> OpenAI:
27
+ """Get an OpenAI client instance.
28
+
29
+ Args:
30
+ env_file: Optional path to environment file
31
+
32
+ Returns:
33
+ OpenAI client instance
34
+
35
+ Raises:
36
+ OpenAINotInstalledError: If OpenAI package is not installed
37
+ """
38
+ settings = UniqueSettings.from_env(env_file=env_file)
39
+ default_headers = get_default_headers(settings.app, settings.auth)
40
+
41
+ return OpenAI(
42
+ api_key=settings.app.key.get_secret_value(),
43
+ base_url=settings.app.base_url + "/openai-proxy/",
44
+ default_headers=default_headers,
45
+ )
@@ -0,0 +1,133 @@
1
+ from collections.abc import Iterable
2
+ from typing import Self
3
+
4
+ from openai.types.chat.chat_completion_assistant_message_param import (
5
+ ChatCompletionAssistantMessageParam,
6
+ ContentArrayOfContentPart,
7
+ )
8
+ from openai.types.chat.chat_completion_content_part_param import (
9
+ ChatCompletionContentPartParam,
10
+ )
11
+ from openai.types.chat.chat_completion_content_part_text_param import (
12
+ ChatCompletionContentPartTextParam,
13
+ )
14
+ from openai.types.chat.chat_completion_developer_message_param import (
15
+ ChatCompletionDeveloperMessageParam,
16
+ )
17
+ from openai.types.chat.chat_completion_function_message_param import (
18
+ ChatCompletionFunctionMessageParam,
19
+ )
20
+ from openai.types.chat.chat_completion_message_param import ChatCompletionMessageParam
21
+ from openai.types.chat.chat_completion_system_message_param import (
22
+ ChatCompletionSystemMessageParam,
23
+ )
24
+ from openai.types.chat.chat_completion_tool_message_param import (
25
+ ChatCompletionToolMessageParam,
26
+ )
27
+ from openai.types.chat.chat_completion_user_message_param import (
28
+ ChatCompletionUserMessageParam,
29
+ )
30
+
31
+
32
+ class OpenAIMessageBuilder:
33
+ def __init__(
34
+ self,
35
+ messages: list[ChatCompletionMessageParam] | None = None,
36
+ ) -> None:
37
+ self._messages: list[ChatCompletionMessageParam] = []
38
+ if messages:
39
+ self._messages = messages
40
+
41
+ @classmethod
42
+ def from_messages(cls, messages: list[ChatCompletionMessageParam]) -> Self:
43
+ builder = cls()
44
+ builder._messages = messages.copy()
45
+ return builder
46
+
47
+ def append_system_message(
48
+ self,
49
+ content: str | Iterable[ChatCompletionContentPartTextParam],
50
+ name: str = "user",
51
+ ) -> Self:
52
+ self._messages.append(
53
+ ChatCompletionSystemMessageParam(
54
+ content=content,
55
+ role="system",
56
+ name=name,
57
+ ),
58
+ )
59
+ return self
60
+
61
+ def append_user_message(
62
+ self,
63
+ content: str | Iterable[ChatCompletionContentPartParam],
64
+ name: str = "user",
65
+ ) -> Self:
66
+ self._messages.append(
67
+ ChatCompletionUserMessageParam(
68
+ content=content,
69
+ role="user",
70
+ name=name,
71
+ ),
72
+ )
73
+ return self
74
+
75
+ def append_assistant_message(
76
+ self,
77
+ content: str | Iterable[ContentArrayOfContentPart],
78
+ name: str = "assistant",
79
+ ) -> Self:
80
+ self._messages.append(
81
+ ChatCompletionAssistantMessageParam(
82
+ content=content,
83
+ role="assistant",
84
+ name=name,
85
+ ),
86
+ )
87
+ return self
88
+
89
+ def append_developper_message(
90
+ self,
91
+ content: str | Iterable[ChatCompletionContentPartTextParam],
92
+ name: str = "developer",
93
+ ) -> Self:
94
+ self._messages.append(
95
+ ChatCompletionDeveloperMessageParam(
96
+ content=content,
97
+ role="developer",
98
+ name=name,
99
+ ),
100
+ )
101
+ return self
102
+
103
+ def append_function_message(
104
+ self,
105
+ content: str | None,
106
+ name: str = "function",
107
+ ) -> Self:
108
+ self._messages.append(
109
+ ChatCompletionFunctionMessageParam(
110
+ content=content,
111
+ role="function",
112
+ name=name,
113
+ ),
114
+ )
115
+ return self
116
+
117
+ def append_tool_message(
118
+ self,
119
+ content: str | Iterable[ChatCompletionContentPartTextParam],
120
+ tool_call_id: str,
121
+ ) -> Self:
122
+ self._messages.append(
123
+ ChatCompletionToolMessageParam(
124
+ content=content,
125
+ role="tool",
126
+ tool_call_id=tool_call_id,
127
+ ),
128
+ )
129
+ return self
130
+
131
+ @property
132
+ def messages(self) -> list[ChatCompletionMessageParam]:
133
+ return self._messages
@@ -0,0 +1,23 @@
1
+ from unique_toolkit.app.unique_settings import UniqueApp, UniqueAuth
2
+
3
+
4
+ def auth_headers(auth_settings: UniqueAuth) -> dict[str, str]:
5
+ return {
6
+ "x-user-id": auth_settings.user_id.get_secret_value(),
7
+ "x-company-id": auth_settings.company_id.get_secret_value(),
8
+ }
9
+
10
+
11
+ def app_headers(app_settings: UniqueApp) -> dict[str, str]:
12
+ return {
13
+ "x-app-id": app_settings.id.get_secret_value(),
14
+ "Authorization": f"Bearer {app_settings.key.get_secret_value()}",
15
+ }
16
+
17
+
18
+ def get_default_headers(app_settings: UniqueApp, auth_settings: UniqueAuth):
19
+ default_headers = {}
20
+ default_headers.update(app_headers(app_settings))
21
+ default_headers.update(auth_headers(auth_settings))
22
+ default_headers["x-api-version"] = "2023-12-06"
23
+ return default_headers
@@ -36,7 +36,6 @@ class LanguageModelName(StrEnum):
36
36
  GEMINI_2_0_FLASH = "litellm:gemini-2-0-flash"
37
37
  GEMINI_2_5_FLASH = "litellm:gemini-2-5-flash"
38
38
  GEMINI_2_5_FLASH_LITE_PREVIEW_0617 = "litellm:gemini-2-5-flash-lite-preview-06-17"
39
- GEMINI_2_5_FLASH_PREVIEW_0417 = "litellm:gemini-2-5-flash-preview-04-17"
40
39
  GEMINI_2_5_FLASH_PREVIEW_0520 = "litellm:gemini-2-5-flash-preview-05-20"
41
40
  GEMINI_2_5_PRO = "litellm:gemini-2-5-pro"
42
41
  GEMINI_2_5_PRO_EXP_0325 = "litellm:gemini-2-5-pro-exp-03-25"
@@ -548,25 +547,6 @@ class LanguageModelInfo(BaseModel):
548
547
  info_cutoff_at=date(2025, 1, day=1),
549
548
  published_at=date(2025, 6, 17),
550
549
  )
551
- case LanguageModelName.GEMINI_2_5_FLASH_PREVIEW_0417:
552
- return cls(
553
- name=model_name,
554
- capabilities=[
555
- ModelCapabilities.FUNCTION_CALLING,
556
- ModelCapabilities.STREAMING,
557
- ModelCapabilities.VISION,
558
- ModelCapabilities.STRUCTURED_OUTPUT,
559
- ModelCapabilities.REASONING,
560
- ],
561
- provider=LanguageModelProvider.LITELLM,
562
- version="gemini-2-5-flash-preview-04-17",
563
- encoder_name=EncoderName.O200K_BASE, # TODO:Replace with LLM tokenizer
564
- token_limits=LanguageModelTokenLimits(
565
- token_limit_input=1_048_576, token_limit_output=65_536
566
- ),
567
- info_cutoff_at=date(2025, 1, day=1),
568
- published_at=date(2025, 4, 1),
569
- )
570
550
  case LanguageModelName.GEMINI_2_5_FLASH_PREVIEW_0520:
571
551
  return cls(
572
552
  name=model_name,
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unique_toolkit
3
- Version: 0.7.38
3
+ Version: 0.7.40
4
4
  Summary:
5
5
  License: Proprietary
6
6
  Author: Martin Fadler
@@ -113,6 +113,13 @@ 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
+ ## [0.7.40] - 2025-07-30
117
+ - Remove `GEMINI_2_5_FLASH_PREVIEW_0417` model
118
+
119
+ ## [0.7.39] - 2025-07-28
120
+ - Implement utitilites to work with openai client
121
+ - Implement utitilites to work with langchain llm
122
+
116
123
  ## [0.7.38] - 2025-07-25
117
124
  - Fix issues with secret strings in settings
118
125
 
@@ -47,12 +47,16 @@ unique_toolkit/evaluators/hallucination/service.py,sha256=k8qro5Lw4Ak58m4HYp3G4H
47
47
  unique_toolkit/evaluators/hallucination/utils.py,sha256=gO2AOzDQwVTev2_5vDKgJ9A6A9e0himJyAta_wglVG8,8326
48
48
  unique_toolkit/evaluators/output_parser.py,sha256=eI72qkzK1dZyUvnfP2SOAQCGBj_-PwX5wy_aLPMsJMY,883
49
49
  unique_toolkit/evaluators/schemas.py,sha256=Jaue6Uhx75X1CyHKWj8sT3RE1JZXTqoLtfLt2xQNCX8,2507
50
+ unique_toolkit/framework_utilities/langchain/client.py,sha256=GWzL2GSxErj52dpYC15w8ABmDB5S2nr2QmV8rKmeEFM,1367
50
51
  unique_toolkit/framework_utilities/langchain/history.py,sha256=8ejA0utPUIlX4z8gtX9IkVFiooY-vOT1UcjI_MoJaAU,638
52
+ unique_toolkit/framework_utilities/openai/client.py,sha256=itbEv098j4alz2Rftp4kbjeloFsAqaxyyBHdZTH5OYM,1297
53
+ unique_toolkit/framework_utilities/openai/message_builder.py,sha256=meJVGPaSQ6xEafNZtACujcD0KXdiSYGTNiv02FSJULE,3834
54
+ unique_toolkit/framework_utilities/utils.py,sha256=JK7g2yMfEx3eMprug26769xqNpS5WJcizf8n2zWMBng,789
51
55
  unique_toolkit/language_model/__init__.py,sha256=lRQyLlbwHbNFf4-0foBU13UGb09lwEeodbVsfsSgaCk,1971
52
56
  unique_toolkit/language_model/builder.py,sha256=69WCcmkm2rMP2-YEH_EjHiEp6OzwjwCs8VbhjVJaCe0,3168
53
57
  unique_toolkit/language_model/constants.py,sha256=B-topqW0r83dkC_25DeQfnPk3n53qzIHUCBS7YJ0-1U,119
54
58
  unique_toolkit/language_model/functions.py,sha256=WhgHbJgz4Z2aZt9TLdOpI0PGyYWA5R90tdwkwdDeT8c,11987
55
- unique_toolkit/language_model/infos.py,sha256=w5__BVG-IiiEYKG1FwM838wzqNbYI3eCCEDocKezc0I,34801
59
+ unique_toolkit/language_model/infos.py,sha256=Abxcw-l7UXkBohxZsigpNz0OUUCtDf404LLr7R-ys4E,33757
56
60
  unique_toolkit/language_model/prompt.py,sha256=JSawaLjQg3VR-E2fK8engFyJnNdk21zaO8pPIodzN4Q,3991
57
61
  unique_toolkit/language_model/reference.py,sha256=nkX2VFz-IrUz8yqyc3G5jUMNwrNpxITBrMEKkbqqYoI,8583
58
62
  unique_toolkit/language_model/schemas.py,sha256=AeuDRJFblGzEYcEMyrlxpOPk12Di3J45I9rT2xZrhEU,14332
@@ -66,7 +70,7 @@ unique_toolkit/short_term_memory/schemas.py,sha256=OhfcXyF6ACdwIXW45sKzjtZX_gkcJ
66
70
  unique_toolkit/short_term_memory/service.py,sha256=8sW7cFJRd4vcRfotJSWb0uHZYl-e5hQWp3G1SddL5Bg,8110
67
71
  unique_toolkit/smart_rules/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
68
72
  unique_toolkit/smart_rules/compile.py,sha256=cxWjb2dxEI2HGsakKdVCkSNi7VK9mr08w5sDcFCQyWI,9553
69
- unique_toolkit-0.7.38.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
70
- unique_toolkit-0.7.38.dist-info/METADATA,sha256=owlyNWn4pHKXlaJae2J3Vyt7ttIgQjrDGTsfaNjOrTg,25266
71
- unique_toolkit-0.7.38.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
72
- unique_toolkit-0.7.38.dist-info/RECORD,,
73
+ unique_toolkit-0.7.40.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
74
+ unique_toolkit-0.7.40.dist-info/METADATA,sha256=gkt3A6p7LNzXPTnDq6MnhoL-r9G_E_WahX6rAzDOXcE,25466
75
+ unique_toolkit-0.7.40.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
76
+ unique_toolkit-0.7.40.dist-info/RECORD,,