unique_toolkit 0.8.3__py3-none-any.whl → 0.8.4__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.
@@ -3,7 +3,7 @@ from pathlib import Path
3
3
  from typing import Self, TypeVar
4
4
  from urllib.parse import urlparse, urlunparse
5
5
 
6
- from pydantic import Field, SecretStr, model_validator
6
+ from pydantic import AliasChoices, Field, SecretStr, model_validator
7
7
  from pydantic_settings import BaseSettings, SettingsConfigDict
8
8
 
9
9
  logger = getLogger(__name__)
@@ -13,18 +13,34 @@ T = TypeVar("T", bound=BaseSettings)
13
13
 
14
14
  def warn_about_defaults(instance: T) -> T:
15
15
  """Log warnings for fields that are using default values."""
16
- for field_name, model_field in instance.model_fields.items():
16
+ for field_name, model_field in instance.__class__.model_fields.items():
17
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
- )
18
+ default_value = model_field.default
19
+
20
+ # Handle SecretStr comparison by comparing the secret values
21
+ if isinstance(field_value, SecretStr) and isinstance(default_value, SecretStr):
22
+ if field_value.get_secret_value() == default_value.get_secret_value():
23
+ logger.warning(
24
+ f"Using default value for '{field_name}': {default_value.get_secret_value()}"
25
+ )
26
+ elif field_value == default_value:
27
+ logger.warning(f"Using default value for '{field_name}': {default_value}")
22
28
  return instance
23
29
 
24
30
 
25
31
  class UniqueApp(BaseSettings):
26
- id: SecretStr = Field(default=SecretStr("dummy_id"))
27
- key: SecretStr = Field(default=SecretStr("dummy_key"))
32
+ id: SecretStr = Field(
33
+ default=SecretStr("dummy_id"),
34
+ validation_alias=AliasChoices(
35
+ "unique_app_id", "app_id", "UNIQUE_APP_ID", "APP_ID"
36
+ ),
37
+ )
38
+ key: SecretStr = Field(
39
+ default=SecretStr("dummy_key"),
40
+ validation_alias=AliasChoices(
41
+ "unique_app_key", "key", "UNIQUE_APP_KEY", "KEY", "API_KEY", "api_key"
42
+ ),
43
+ )
28
44
  base_url: str = Field(
29
45
  default="http://localhost:8092/",
30
46
  deprecated="Use UniqueApi.base_url instead",
@@ -48,8 +64,16 @@ class UniqueApi(BaseSettings):
48
64
  base_url: str = Field(
49
65
  default="http://localhost:8092/",
50
66
  description="The base URL of the Unique API. Ask your admin to provide you with the correct URL.",
67
+ validation_alias=AliasChoices(
68
+ "unique_api_base_url", "base_url", "UNIQUE_API_BASE_URL", "BASE_URL"
69
+ ),
70
+ )
71
+ version: str = Field(
72
+ default="2023-12-06",
73
+ validation_alias=AliasChoices(
74
+ "unique_api_version", "version", "UNIQUE_API_VERSION", "VERSION"
75
+ ),
51
76
  )
52
- version: str = Field(default="2023-12-06")
53
77
 
54
78
  model_config = SettingsConfigDict(
55
79
  env_prefix="unique_api_",
@@ -82,14 +106,29 @@ class UniqueApi(BaseSettings):
82
106
 
83
107
  def openai_proxy_url(self) -> str:
84
108
  parsed = urlparse(self.base_url)
85
- return urlunparse(
86
- parsed._replace(path="/public/openai-proxy/", query=None, fragment=None)
87
- )
109
+ path = "/public/chat/openai-proxy/"
110
+ if parsed.hostname and "qa.unique" in parsed.hostname:
111
+ path = "/public/chat-gen2/openai-proxy/"
112
+
113
+ return urlunparse(parsed._replace(path=path, query=None, fragment=None))
88
114
 
89
115
 
90
116
  class UniqueAuth(BaseSettings):
91
- company_id: SecretStr = Field(default=SecretStr("dummy_company_id"))
92
- user_id: SecretStr = Field(default=SecretStr("dummy_user_id"))
117
+ company_id: SecretStr = Field(
118
+ default=SecretStr("dummy_company_id"),
119
+ validation_alias=AliasChoices(
120
+ "unique_auth_company_id",
121
+ "company_id",
122
+ "UNIQUE_AUTH_COMPANY_ID",
123
+ "COMPANY_ID",
124
+ ),
125
+ )
126
+ user_id: SecretStr = Field(
127
+ default=SecretStr("dummy_user_id"),
128
+ validation_alias=AliasChoices(
129
+ "unique_auth_user_id", "user_id", "UNIQUE_AUTH_USER_ID", "USER_ID"
130
+ ),
131
+ )
93
132
 
94
133
  model_config = SettingsConfigDict(
95
134
  env_prefix="unique_auth_",
@@ -128,7 +167,7 @@ class UniqueSettings:
128
167
 
129
168
  # Initialize settings with environment file if provided
130
169
  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)
170
+ auth = UniqueAuth(_env_file=env_file_str) # type: ignore[call-arg]
171
+ app = UniqueApp(_env_file=env_file_str) # type: ignore[call-arg]
172
+ api = UniqueApi(_env_file=env_file_str) # type: ignore[call-arg]
134
173
  return cls(auth=auth, app=app, api=api)
@@ -10,9 +10,9 @@ def unique_history_to_langchain_history(
10
10
  history = []
11
11
  for m in unique_history:
12
12
  if m.role == UniqueRole.ASSISTANT:
13
- history.append(AIMessage(content=m.content))
13
+ history.append(AIMessage(content=m.content or ""))
14
14
  elif m.role == UniqueRole.USER:
15
- history.append(HumanMessage(content=m.content))
15
+ history.append(HumanMessage(content=m.content or ""))
16
16
  else:
17
17
  raise Exception("Unknown message role.")
18
18
 
@@ -37,7 +37,7 @@ def get_openai_client(unique_settings: UniqueSettings) -> OpenAI:
37
37
  default_headers = get_default_headers(unique_settings.app, unique_settings.auth)
38
38
 
39
39
  return OpenAI(
40
- api_key=unique_settings.app.key.get_secret_value(),
40
+ api_key="dummy_key",
41
41
  base_url=unique_settings.api.openai_proxy_url(),
42
42
  default_headers=default_headers,
43
43
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: unique_toolkit
3
- Version: 0.8.3
3
+ Version: 0.8.4
4
4
  Summary:
5
5
  License: Proprietary
6
6
  Author: Martin Fadler
@@ -113,6 +113,9 @@ 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.8.4] - 2025-08-06
117
+ - Make unique settings compatible with legacy environment variables
118
+
116
119
  ## [0.8.3] - 2025-08-05
117
120
  - Expose threshold field for search.
118
121
 
@@ -11,7 +11,7 @@ unique_toolkit/app/init_sdk.py,sha256=5_oDoETr6akwYyBCb0ivTdMNu3SVgPSkrXcDS6ELyY
11
11
  unique_toolkit/app/performance/async_tasks.py,sha256=H0l3OAcosLwNHZ8d2pd-Di4wHIXfclEvagi5kfqLFPA,1941
12
12
  unique_toolkit/app/performance/async_wrapper.py,sha256=yVVcRDkcdyfjsxro-N29SBvi-7773wnfDplef6-y8xw,1077
13
13
  unique_toolkit/app/schemas.py,sha256=JdC2rNVPRrr6QhGMZweE0ID760onbRY2oq9m1LVFego,7429
14
- unique_toolkit/app/unique_settings.py,sha256=YwKXKKSrLSoNk5kow5ChC0uOqii37gd3ttFL4rSAVF4,4443
14
+ unique_toolkit/app/unique_settings.py,sha256=Gn8qxy_hNraVTTlP4wfZJzgxPU8cU6s84Uw6FK6ixGg,5946
15
15
  unique_toolkit/app/verification.py,sha256=GxFFwcJMy25fCA_Xe89wKW7bgqOu8PAs5y8QpHF0GSc,3861
16
16
  unique_toolkit/chat/__init__.py,sha256=LRs2G-JTVuci4lbtHTkVUiNcZcSR6uqqfnAyo7af6nY,619
17
17
  unique_toolkit/chat/constants.py,sha256=05kq6zjqUVB2d6_P7s-90nbljpB3ryxwCI-CAz0r2O4,83
@@ -47,8 +47,8 @@ unique_toolkit/evaluators/hallucination/utils.py,sha256=gO2AOzDQwVTev2_5vDKgJ9A6
47
47
  unique_toolkit/evaluators/output_parser.py,sha256=eI72qkzK1dZyUvnfP2SOAQCGBj_-PwX5wy_aLPMsJMY,883
48
48
  unique_toolkit/evaluators/schemas.py,sha256=Jaue6Uhx75X1CyHKWj8sT3RE1JZXTqoLtfLt2xQNCX8,2507
49
49
  unique_toolkit/framework_utilities/langchain/client.py,sha256=Msfmr7uezwqagyRJ2zjWbQRFqzDExWYK0y5KLEnDNqM,1329
50
- unique_toolkit/framework_utilities/langchain/history.py,sha256=8ejA0utPUIlX4z8gtX9IkVFiooY-vOT1UcjI_MoJaAU,638
51
- unique_toolkit/framework_utilities/openai/client.py,sha256=Zs5zxFbRfa0XrlbZvhGf-GpHomKLBJx0D28iowk1Eek,1236
50
+ unique_toolkit/framework_utilities/langchain/history.py,sha256=R9RuCeSFNaUO3OZ0G_LmIC4gmOCIANcl91MfyWLnZ1c,650
51
+ unique_toolkit/framework_utilities/openai/client.py,sha256=IasxPXlVJHIsZdXHin7yq-5tO4RNLUu9cEuhrgb4ghE,1205
52
52
  unique_toolkit/framework_utilities/openai/message_builder.py,sha256=meJVGPaSQ6xEafNZtACujcD0KXdiSYGTNiv02FSJULE,3834
53
53
  unique_toolkit/framework_utilities/utils.py,sha256=JK7g2yMfEx3eMprug26769xqNpS5WJcizf8n2zWMBng,789
54
54
  unique_toolkit/language_model/__init__.py,sha256=lRQyLlbwHbNFf4-0foBU13UGb09lwEeodbVsfsSgaCk,1971
@@ -73,7 +73,7 @@ unique_toolkit/tools/tool_definitions.py,sha256=YYu53vXMJBeJtuSU1L_FJBsiN52LSA5L
73
73
  unique_toolkit/tools/tool_definitionsV2.py,sha256=yjLmP85pFGd1QtIVMC3oLQPSQ2NckBj9hIihjIr2FZg,5728
74
74
  unique_toolkit/tools/tool_factory.py,sha256=ux11jd7Oobb-6eBeS51T-tviH14k6HKqsKmljA7h6qA,879
75
75
  unique_toolkit/tools/tool_progress_reporter.py,sha256=AyPdgxpd48qotJyPB8qJ7h7ghiv2w2EK8nlyqQVFRt4,8048
76
- unique_toolkit-0.8.3.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
77
- unique_toolkit-0.8.3.dist-info/METADATA,sha256=UEfARrL_5zaX43AazPC7fxsW53RVJO0lwJAOlzc3hUQ,26086
78
- unique_toolkit-0.8.3.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
79
- unique_toolkit-0.8.3.dist-info/RECORD,,
76
+ unique_toolkit-0.8.4.dist-info/LICENSE,sha256=GlN8wHNdh53xwOPg44URnwag6TEolCjoq3YD_KrWgss,193
77
+ unique_toolkit-0.8.4.dist-info/METADATA,sha256=l-59S348l-GsL9MWnt8MbhSalpI1wTmv61Tp7EUmchk,26179
78
+ unique_toolkit-0.8.4.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
79
+ unique_toolkit-0.8.4.dist-info/RECORD,,