diff --git a/src/uipath/llm_client/settings/platform/settings.py b/src/uipath/llm_client/settings/platform/settings.py index 7c4f63c7..278dc810 100644 --- a/src/uipath/llm_client/settings/platform/settings.py +++ b/src/uipath/llm_client/settings/platform/settings.py @@ -7,7 +7,7 @@ from pydantic import Field, SecretStr, model_validator from typing_extensions import override from uipath.platform import UiPath -from uipath.platform.common import EndpointManager +from uipath.platform.common import EndpointManager, resolve_service_url from uipath.platform.common._config import UiPathConfig from uipath.platform.common.constants import ( ENV_BASE_URL, @@ -121,7 +121,7 @@ def build_base_url( api_config.routing_mode == RoutingMode.NORMALIZED and api_config.api_type == ApiType.COMPLETIONS ): - url = f"{self.base_url}/{EndpointManager.get_normalized_endpoint()}" + endpoint_path = EndpointManager.get_normalized_endpoint() elif ( api_config.routing_mode == RoutingMode.NORMALIZED and api_config.api_type == ApiType.EMBEDDINGS @@ -135,7 +135,12 @@ def build_base_url( and api_config.api_type == ApiType.COMPLETIONS ): endpoint = EndpointManager.get_vendor_endpoint() - url = f"{self.base_url}/{self._format_endpoint(endpoint, model=model_name, vendor=api_config.vendor_type, api_version=api_config.api_version)}" + endpoint_path = self._format_endpoint( + endpoint, + model=model_name, + vendor=api_config.vendor_type, + api_version=api_config.api_version, + ) elif ( api_config.routing_mode == RoutingMode.PASSTHROUGH and api_config.api_type == ApiType.EMBEDDINGS @@ -146,10 +151,16 @@ def build_base_url( f"got vendor_type='{api_config.vendor_type}'." ) endpoint = EndpointManager.get_embeddings_endpoint() - url = f"{self.base_url}/{self._format_endpoint(endpoint, model=model_name, api_version=api_config.api_version)}" + endpoint_path = self._format_endpoint( + endpoint, model=model_name, api_version=api_config.api_version + ) else: raise ValueError(f"Invalid API configuration: {api_config}") - return url + + override_url = resolve_service_url(endpoint_path) + if override_url: + return override_url + return f"{self.base_url}/{endpoint_path}" @override def build_auth_headers( diff --git a/tests/core/features/settings/test_platform.py b/tests/core/features/settings/test_platform.py index 69297e35..e64cfbc9 100644 --- a/tests/core/features/settings/test_platform.py +++ b/tests/core/features/settings/test_platform.py @@ -57,6 +57,40 @@ def test_build_base_url_normalized( ) assert "agenthub_/llm/api/chat/completions" in url + def test_build_base_url_uses_service_override_when_set( + self, platform_env_vars, mock_platform_auth, normalized_api_config + ): + """A UIPATH_SERVICE_URL_ override redirects to the local server, + stripping the org/tenant and service prefix.""" + env = { + **platform_env_vars, + "UIPATH_SERVICE_URL_AGENTHUB": "http://localhost:8080", + } + with patch.dict(os.environ, env, clear=True): + settings = PlatformSettings() + url = settings.build_base_url( + model_name="gpt-4o", + api_config=normalized_api_config, + ) + assert url == "http://localhost:8080/llm/api/chat/completions" + + def test_build_base_url_ignores_unrelated_service_override( + self, platform_env_vars, mock_platform_auth, normalized_api_config + ): + """An override for a different service must not affect the built URL.""" + env = { + **platform_env_vars, + "UIPATH_SERVICE_URL_ORCHESTRATOR": "http://localhost:8080", + } + with patch.dict(os.environ, env, clear=True): + settings = PlatformSettings() + url = settings.build_base_url( + model_name="gpt-4o", + api_config=normalized_api_config, + ) + assert "localhost" not in url + assert "agenthub_/llm/api/chat/completions" in url + def test_build_auth_headers_omits_agenthub_config_by_default( self, platform_env_vars, mock_platform_auth ):